答案是CLI与Web SAPI使用不同PHP实例或ext-fileinfo未启用;需通过php -r "echo PHP_BINARY;"、phpinfo()和composer show --platform交叉验证版本与扩展一致性,并启用fileinfo扩展。

PHP 8.3 配置“看起来满足”,但代码一跑就挂,八成不是版本号没对上,而是 composer show --platform 和 php -v 对不上,或者关键扩展压根没启用。
CLI 和 Web SAPI 用的不是同一个 PHP
你敲 php -v 看到 8.3,不代表浏览器访问时也是 8.3。Apache、Nginx 或 PHP-FPM 很可能在调另一个 PHP 实例。
- Windows 执行
where php,看输出是不是多个路径——第一个未必是你装的 8.3;Linux/macOS 执行which php,再对比php -r "echo PHP_BINARY;",两者路径不一致就铁定出问题 - Web 端验证:建个
info.php,内容是<?php phpinfo(); ?>,访问它,直接看 “Loaded Configuration File” 和 “PHP Version” 行 - Apache 要确认
LoadModule php_module指向的是 8.3 的php8.dll(Windows)或libphp.so(Linux);Nginx 则检查fastcgi_pass是否指向正确的 PHP-FPM socket 或端口,且该 FPM 进程确实是 8.3 启动的
ext-fileinfo 缺失导致依赖装不全
ThinkPHP 8、Laravel 11 等框架报 “platform does not satisfy” 错误,90% 是因为 ext-fileinfo 没开,而不是 PHP 版本低。
- Windows:打开
php.ini,取消注释这行:extension=php_fileinfo.dll,保存后重启 CLI(关掉终端重开)和 Web 服务(如 Apache 或 php-fpm) - Ubuntu/Debian:
sudo apt install php-fileinfo,然后sudo systemctl restart apache2或sudo systemctl restart php8.3-fpm - 验证是否生效:
php -m | grep fileinfo有输出才算成功;composer show --platform里也要看到ext-fileinfo为 true
动态属性或只读属性触发弃用/致命错误
PHP 8.3 默认对未声明属性赋值发 Deprecated: Creation of dynamic property,对未初始化的 readonly 属性访问直接报 Fatal error: Uninitialized readonly property —— 这些不会在 php -l 里暴露,只在运行时炸。
立即学习“PHP免费学习笔记(深入)”;
- 老代码里类似
$obj->foo = 'bar';($obj是普通类,没声明$foo)会触发弃用通知;加了error_reporting(E_ALL)就能看到,否则静默失败 -
public readonly string $name = 'default';这种写法在 8.3 里默认值无效,必须在__construct()里显式赋值,否则一访问就崩 - WordPress 插件/主题若用了动态属性又没加
#[AllowDynamicProperties],后台白屏或设置保存失败就是这个原因
Composer platform 锁定没生效,CI/CD 环境漏配
本地能跑不代表上线能跑。CI 流水线用 PHP 8.2 安装依赖,但代码用了 8.3 的新特性(比如只读类),部署后直接 Fatal error。
- 别只信
php -v,执行composer config platform.php 8.3.0,这条命令会把平台版本硬编码进composer.json的config.platform字段 - 值必须是完整语义版本(
8.3.0),写^8.3或8.3会被忽略 - 提交
composer.json到 Git,确保 CI 环境读到的是锁定后的配置,而不是靠它自己猜当前 PHP 版本
最常被跳过的动作是验证 composer show --platform 和 Web 端 phpinfo() 输出是否完全一致——这两个不统一,其他所有配置都白搭。



















