PHP 8 存在大量向后不兼容变更,如移除 mysql_* 函数、强化类型系统、禁用隐式转换、新增 ValueError/TypeError 等,需分阶段升级并全面适配代码、扩展及第三方库。
PHP 8 不是简单升级,而是有大量**向后不兼容变更**。直接运行旧代码大概率报错或行为异常,尤其 PHP 5.6 或更早项目迁移时,mysql_* 函数、create_function()、隐式转换逻辑等已彻底移除。
mysql_connect()、mysql_query() 等函数在 PHP 7.0 就被废弃,PHP 8.0 中完全不存在 —— 必须改用 PDO 或 mysqli
each()、mysql_escape_string()、dl() 等已删除,调用即致命错误 Fatal error: Uncaught Error: Call to undefined function
json_decode($str, null) 第二个参数不能为 null(必须是 true 或 false),否则抛 TypeError
$obj['key'])在 PHP 7.x 仅警告,PHP 8.0+ 直接抛 TypeError
升级后最常遇到的错误不是语法错,而是语义/行为变更引发的运行时异常。需重点检查:
Warning: A non-numeric value encountered → 多出现在字符串与数字混用场景(如 '123abc' + 456),PHP 8 默认禁用隐式转换,应先用 is_numeric() 或 filter_var($val, FILTER_VALIDATE_INT) 校验Fatal error: Array and string offset access syntax with curly braces is no longer supported → 替换所有 $str{0} 为 $str[0]
Uncaught TypeError: strlen(): Argument #1 ($string) must be of type string, null given → PHP 8 启用严格类型校验,函数参数不再自动转类型,需显式判断:strlen($str ?? '
') 或 is_string($str) ? strlen($str) : 0
Deprecated: Function get_magic_quotes_gpc() is deprecated → 该函数早在 PHP 7.4 废弃,PHP 8 删除;现代应用不应依赖 magic quotes,应统一使用预处理或 htmlspecialchars() 输出转义别只盯着自己写的代码 —— 你用的 Composer 包很可能卡在 PHP 7.2 或 7.4。执行 composer update 前务必确认:
composer.json 中 "php": "^7.4" 这类约束,需升级为 "^8.0" 或 "^8.1"
mcrypt 已被移除,需迁移到 openssl;ext-mongo 被 ext-mongodb 替代,API 完全不同composer why-not php:8.2 可定位阻塞升级的具体包及其版本限制跳过 PHP 7 直升 PHP 8 风险极高。推荐分阶段推进,每步验证后再继续:
error_reporting = E_ALL | E_STRICT,修复所有 Deprecated 和 Notice 级别提示php -l 批量扫描文件语法,再用 phpstan 或 psalm 做静态分析,提前发现类型不匹配、未定义变量等问题set_error_handler() 和 set_exception_handler(),记录 PHP 8 新增的 TypeError、ValueError 实例mysql_* 全部替换为 mysqli 面向对象写法(如 (new mysqli($host, $user, $pass))->query($sql)),避免 PDO 配置陷阱if (!is_string($input)) {
throw new ValueError('Expected string, got ' . gettype($input));
}
return mb_strtoupper($input);
PHP 8 的 ValueError 和 TypeError 是新异常类型,比传统 Exception 更精确,但老代码若只捕获 Exception 会漏掉它们 —— 这点极易被忽略。