ThinkPHP8在PHP8下必须彻底替换废弃mysql_*函数并确保PDO MySQL配置正确。需全局搜索删除旧函数,确认database.php中type为'mysql'且hostname为127.0.0.1、hostport=3306、database真实存在;启用pdo_mysql扩展;改用Db类或模型操作;使用app()替代Facade;配置PDO异常模式防静默失败。

ThinkPHP8项目在PHP8环境下运行时,若仍残留废弃的mysql_*函数调用或错误配置type为'mysql'(非PDO封装层),将直接触发Fatal error或连接静默失败,必须彻底替换为PDO兼容路径。
确认废弃函数是否真实存在
执行全局搜索:grep -r "mysql_connect\|mysql_query\|mysql_fetch_array\|mysql_error" app/ extend/ common/ --include="*.php"
重点检查第三方扩展包(如旧版验证码、支付SDK)和自定义数据库工具类——这些地方最容易藏匿已移除函数。若搜到结果,【必须全部删除或重写】,不能仅注释。
注意:即使框架默认走Db类,只要代码里明写mysql_connect(),PHP8就会立即报错终止,不给任何机会。
立即学习“PHP免费学习笔记(深入)”;
修正database.php中的驱动类型
打开config/database.php,定位到'type'配置项。
把'type' => 'mysql'改成'type' => 'mysql'——等等,别急着改!这里不是让你换文字,而是确认它**本来就是'mysql'**。ThinkPHP8不接受'type'=>'pdo'这种写法,否则会抛Class not found异常。
真正要改的是底层行为:确保'type'值为小写'mysql',且同时满足以下三点:【'hostname'必须是127.0.0.1而非localhost】、'hostport'显式设为3306、'database'指向一个已创建的真实库名。
启用并验证PDO MySQL扩展
第一步:编辑php.ini,取消以下三行前的分号:
extension=mbstring
extension=openssl
extension=pdo_mysql
第二步:重启Web服务器(Apache/Nginx)和PHP-FPM进程,然后执行php -m | findstr pdo_mysql(Windows)或php -m | grep pdo_mysql(Linux/macOS)确认扩展已加载。
第三步:在项目根目录新建test_pdo.php,写入:
<?php
$dsn = "mysql:host=127.0.0.1;dbname=test_db;charset=utf8mb4";
try {
$pdo = new PDO($dsn, "root", "", [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
echo "PDO连接成功";
} catch (Exception $e) {
die("PDO失败:" . $e->getMessage());
}
重构遗留代码为Db类调用
方法一:直接替换原生mysql_*调用
将mysql_query("SELECT * FROM user") → \think\Db::query("SELECT * FROM user")
将mysql_fetch_array($result) → $result本身已是数组,无需再fetch;若需遍历,直接foreach($result as $row)
方法二:改用模型操作(推荐)
新建app/model/User.php,继承think\Model;之后用UserModel::where('id', 1)->find()替代所有手写SQL查询。这能自动触发事件、自动转换时间戳、规避SQL注入风险。
方法三:依赖注入替代Facade(关键升级点)
把Cache::get('token') → app('cache')->get('token')
把Config::get('app.debug') → app('config')->get('app.debug')
这一步能绕过PHP8.0+对__callStatic返回类型的强制校验,避免TypeError。
强制PDO异常模式防静默失败
在config/database.php的'database'配置块内,添加params数组:
'params' => [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
],
没有这个配置,PDO默认可能使用PDO::ERRMODE_SILENT,导致SQL语法错误被吞掉,只返回false,调试时完全找不到问题源头。



















