返回

Debian 10 PHP 多版本冲突及 MySQL 连接失败解决

php

Debian 10 上混乱的 PHP 多版本问题排查与解决

最近,我接手了一个有点棘手的 Debian 10 系统。上面存着大概 20 年的客户记录,我的任务是恢复这些数据。 看起来问题源于之前从 Debian 9 到 Debian 10 的升级。

最初,MySQL 数据库出了问题。不过,最终我还是安装了 MariaDB,并且能通过命令行界面看到需要的数据库。 但是,基本上所有需要连接 MySQL 的 PHP 程序都运行出错,报各种各样的错误。例如,PHPMyAdmin 提示找不到 MYSQLI 扩展,即使我已经在 PHP 配置显示的扩展目录下放了 mysqli.so 文件。

如果通过浏览器访问 phpinfo.php,页面显示 PHP 版本是 5.6。 而在命令行运行 php -v,显示的却是 PHP 7.0。 我一直没法搞定这个问题。所以,考虑彻底删除这两个版本的 PHP,然后重新安装 Debian 10 对应的正确版本。

或者有其他思路也请赐教。 我是在整个硬盘的克隆副本上操作,所以不太担心会搞出什么大乱子。实在不行,我打算全新安装 Debian 12,然后迁移整个 /var/www 目录。

先谢过大家!

我尝试过手动添加 mysqli.so 文件到 PHP 识别的 EXTENSIONS_DIR 目录。结果, PHPMyAdmin 抛出了 JSON 扩展丢失的错误。我推测是系统在两个不同的PHP安装之间混淆了。

补充一下:PHP 程序貌似都能正常工作,除了那些需要 MySQL 功能的部分 。也有可能是需要彻底删除和重装 MySQL 。数据备份是有的,也许可以试试,但我目前重新连接PHP和MySQL的尝试都没有成功。

问题原因分析

出现这种混乱情况,可能的原因有这么几个:

  1. 升级过程出错: 从 Debian 9 升级到 Debian 10 的过程中,PHP 和相关的包可能没有正确地升级或配置。这会导致旧版本的 PHP 残留,同时新版本的 PHP 又没有完全配置好。

  2. 手动安装/配置: 为了尝试修复问题,可能曾经手动安装或配置过 PHP 或相关组件,导致系统中的 PHP 环境更加混乱。

  3. 软件源问题: 可能添加了不正确的软件源或使用了不同版本的软件包,导致依赖关系出现冲突。

  4. Apache/PHP 配置问题: Apache 虚拟主机或者 PHP 自身的配置可能存在问题,导致调用了错误的PHP版本。

解决方案

考虑到数据恢复是首要目标,并且你有硬盘克隆,可以大胆尝试以下几种方法。我会按推荐程度排序。

方案一:修复现有环境 (优先推荐)

与其直接删除,不如尝试先弄清哪个环节出了问题。

  1. 明确当前生效的 PHP 配置

    先搞清楚 Apache (假设你在用 Apache) 用的是哪个 PHP 版本。 看看 /etc/apache2/mods-enabled/ 下有关 PHP 的软链接。 例如:

    ls -l /etc/apache2/mods-enabled/ | grep php
    

    如果链接到了类似 php5.6.confphp5.6.loadphp7.0.confphp7.0.load 的文件,就能知道当前 Apache 使用的是哪个版本。

  2. 查看 php.ini 文件路径

    分别通过命令行和网页获取 phpinfo() 输出,对比 Loaded Configuration File 所指向的 php.ini 位置是否一致。 这样就能分别确定CLI 和 web 环境各自使用了哪个配置文件。

    命令行下:

    php -i | grep "Loaded Configuration File"
    

    网页 (phpinfo.php): 找到 Loaded Configuration File 这一项。

  3. 统一 php.ini 配置:
    如果上面两步发现 php.ini 路径不一致,则需要针对网页的 PHP 版本(例如,如果是5.6),编辑其对应的 php.ini, 确保启用了 mysqli 和 json 扩展。
    查找:

    ;extension=mysqli
    ;extension=json
    

    去除行首的分号(;),保存文件并重启 Apache 服务。

    sudo systemctl restart apache2
    
  4. 检查扩展目录:

    在 php.ini 文件中, 找到 extension_dir 指令。确保其路径是正确的,并且 mysqli.sojson.so (或者编译进PHP的) 文件存在于这个目录下。

  5. (可选)强制使用特定版本的 PHP 模块(针对Apache)

    如果你想强制 Apache 使用某个特定版本的 PHP (例如 7.0), 可以这样做:

    sudo a2dismod php5.6  # 禁用 PHP 5.6 模块
    sudo a2enmod php7.0   # 启用 PHP 7.0 模块
    sudo systemctl restart apache2
    
  6. 确认MySQLi 是否正常加载 :

修改 phpinfo.php, 添加:

<?php
    phpinfo();
    if (function_exists('mysqli_connect')) {
        echo "mysqli is working fine";
    } else{
         echo "mysqli is not working!!";
    }
?>

如果页面打印出"mysqli is not working!!", 接下来集中解决这个问题.

  1. 测试连接数据库 :

创建 test_db.php:

<?php
$servername = "localhost";
$username = "your_db_username";  // 替换成你的数据库用户名
$password = "your_db_password"; // 替换成你的数据库密码
$dbname = "your_database_name"; // 替换成你的数据库名

// 创建连接
$conn = new mysqli($servername, $username, $password, $dbname);

// 检测连接
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
echo "Connected successfully";
$conn->close();
?>

方案二:彻底移除并重新安装 PHP (如果方案一无效)

如果问题还是没解决,那么干净地重装 PHP 也许是最好的办法.

  1. 停止 Apache 服务:

    sudo systemctl stop apache2
    
  2. 列出所有已安装的 PHP 相关包:

    dpkg -l | grep php
    

    这条命令会列出所有名字中包含 "php" 的包。

  3. 彻底删除这些包 (包括配置文件):

    sudo apt purge <package_name1> <package_name2> ...
    

    用上面 dpkg -l 命令列出的包名替换 <package_name1><package_name2> 等。 注意:小心操作,只删除你确定是 PHP 相关的包,不要误删其他重要的包。 你可以分批次操作,一次移除一类,比如先移除所有php5.6-的包,然后再移除php7.0-

    一个更便捷(也更危险)的方式, 使用通配符(*): 谨慎使用.

    sudo apt purge php5.6* php7.0*
    
  4. 清除残留文件(可选,但推荐):

    有时候,即使卸载了包,还会留下一些配置文件或目录。可以用以下命令查找并删除:

    sudo find / -name "*php5.6*" -exec rm -rf {} \;
    sudo find / -name "*php7.0*" -exec rm -rf {} \;
    

    再次提醒,务必谨慎,确认无误再执行.

  5. 更新包列表:

    sudo apt update
    
  6. 安装 Debian 10 默认的 PHP 版本(当前应该是 PHP 7.3):

    sudo apt install php php-mysql php-cli php-fpm php-json php-opcache php-mbstring php-xml php-gd php-curl
    

    这一步会安装 PHP 和一些常用的扩展。

  7. (如果使用Apache)重新安装并配置PHP 模块 :

    sudo apt install libapache2-mod-php
    sudo a2enmod php7.3
    sudo systemctl restart apache2
    
  8. 验证安装:

    创建或修改 /var/www/html/phpinfo.php 文件(假设这是你的 web 根目录):

    <?php
    phpinfo();
    ?>
    

    然后通过浏览器访问 http://your_server_ip/phpinfo.php。 如果看到 PHP 信息页面,并且版本是 7.3,则表示安装成功。

    再次执行方案一中第6和第7步,测试mysqli功能.

  9. 进阶:处理 php-fpm

如果系统用了 php-fpm, 则上面配置会有些不同,这里不做展开. 简单提几点:

*   需要配置 Apache 的代理,让其转发请求给 php-fpm。
*   php-fpm 也有自己的配置文件(通常在 /etc/php/7.3/fpm/php.ini 和 /etc/php/7.3/fpm/pool.d/www.conf),需要根据需要进行调整。
*  需要重启 php7.3-fpm 服务:

```
 sudo systemctl restart php7.3-fpm
```

方案三: 只重装 MariaDB (如果怀疑数据库配置有问题)

如果 PHP 程序可以正常运行,但只有访问数据库的功能不行,也许应该集中处理一下 MariaDB。

  1. 备份数据:
    mysqldump -u root -p --all-databases > all_databases.sql
    

输入root 密码后,所有的数据库将会被导出。

  1. 停止MariaDB 服务:
  sudo systemctl stop mariadb
  1. 卸载 MariaDB:

    sudo apt purge mariadb-server mariadb-client
    
  2. 删除 MariaDB 数据目录(谨慎操作):

    sudo rm -rf /var/lib/mysql
    
  3. 重新安装 MariaDB:

    sudo apt install mariadb-server mariadb-client
    
  4. 安全配置(可选,但强烈推荐):

    sudo mysql_secure_installation
    

    这个脚本会引导你设置 root 密码、删除匿名用户、禁止 root 远程登录等,增强安全性。

  5. 还原数据:

mysql -u root -p < all_databases.sql
  1. 再次执行方案一中第6和第7步,测试mysqli功能.

额外安全建议(适用于所有方案):

  • 定期备份: 养成定期备份数据库和重要文件的习惯,避免数据丢失。
  • 更新软件: 保持系统和软件的最新状态,及时安装安全补丁。
  • 最小权限原则: 为数据库用户设置最小必要的权限,不要直接使用 root 用户操作数据库。
  • 强密码策略: 设置数据库复杂密码,定期修改。
  • 防火墙 : 只允许必要的端口连接数据库.