Laravel 6及更早版本、PHPUnit

哪些主流框架在 PHP 8 下跑不起来?
不是所有 PHP 7.x 能用的框架,PHP 8 一装就稳。Laravel 8+、Symfony 5.4+、Yii 3 都已原生适配 PHP 8;但 Laravel 6 或更早版本(尤其搭配 doctrine/dbal )会在启动时抛出 Fatal error: Uncaught TypeError,因为 PHP 8 强制要求接口方法签名完全一致,而旧版 Doctrine 的 getDatabasePlatform() 返回类型声明缺失或不匹配。
常见断裂点:
phpunit/phpunit :调用assertInternalType()会直接报错,PHP 8 已移除该断言,必须升级到 PHPUnit 9.3+ 并改用assertIsArray()等新方法monolog/monolog :在 PHP 8 中触发Deprecated: Required parameter $context follows optional parameter $level,因构造函数参数顺序与默认值定义违反 PHP 8 新的严格签名规则guzzlehttp/guzzle :GuzzleHttp\Client::__construct()的配置数组处理逻辑在 PHP 8 下对空数组键判断失效,导致请求头丢失
扩展模块被删或行为突变,哪些要立刻查?
PHP 8 移除了 11 个过时扩展,包括 mysql(早已废弃)、sybase、firebird、wddx;还把 ext/mcrypt 彻底踢出核心——如果你项目里还写着 mcrypt_encrypt(),升级后直接 Fatal error: Uncaught Error: Call to undefined function mcrypt_encrypt()。
没被删但“悄悄改了”的关键扩展:
立即学习“PHP免费学习笔记(深入)”;
-
mbstring:mb_detect_encoding()在 PHP 8 中默认不再尝试ASCII编码,若旧代码依赖其自动 fallback 行为,可能误判编码,需显式传入['UTF-8', 'GBK', 'ASCII'] -
json:json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR)在 PHP 7 是静默截断,PHP 8 改为抛出JsonException,必须用try/catch包裹 -
pdo_mysql:预处理语句绑定参数时,PDO::PARAM_INT对浮点数强制转整型的行为更严格,bindParam(':id', $val, PDO::PARAM_INT)中若$val = 3.9,PHP 7 得到3,PHP 8 报TypeError
Composer 依赖锁死和平台配置怎么写才不翻车?
光改 php 版本号不够。很多包的 composer.json 里写着 "php": "^7.2",即使你本地是 PHP 8.4,Composer 仍会按 PHP 7 规则解析依赖树,可能装进不兼容的旧版子包。
必须做两件事:
- 在根项目
composer.json中明确声明:"platform": {"php": "8.4.0"},强制 Composer 按 PHP 8.4 解析依赖约束 - 运行
composer update --with-all-dependencies,而非composer update,否则symfony/console这类间接依赖可能卡在 v5.4(仅支持 PHP 7.2+)而拒绝升级到 v6+(需 PHP 8.0+) - 检查
composer.lock里的platform-check字段是否为true,否则 CI 环境可能跳过平台校验,上线后才暴露问题
宝塔/AMH 面板里切 PHP 8 后,扩展没加载?
宝塔 PHP 8.4 默认不启用 opcache 和 redis 扩展——和 PHP 7.x 安装包策略不同。你看到面板里“已安装”,不代表 php -m | grep redis 能输出结果。
实操步骤:
- 进宝塔 → 软件商店 → 找到对应 PHP 版本 → 点击“设置” → “安装扩展”,手动勾选
opcache、redis、memcached(如果用了) - 编辑
/www/server/php/84/etc/php.ini,确认存在zend_extension=opcache.so且未被注释;extension=redis.so行末不能带分号 - 重启 PHP 服务后,执行
php -r "echo extension_loaded('redis') ? 'ok' : 'fail';"验证,别只信面板图标
最常被忽略的是 opcache.preload:PHP 8 的性能收益大头在这儿,不是 JIT。但宝塔不会自动生成 preload 文件,你得自己写好 preload.php,再在 php.ini 里配 opcache.preload=/path/to/preload.php,否则 opcache 就是半残状态。











