PHP 7.4 升级到 8.1 后报错核心是类型安全收紧、函数废弃和错误升级:str_contains()等传null直接TypeError;mysql_*、create_function()被彻底移除;方法重写需严格协变;扩展须匹配ABI 20200930;JSON需显式处理NaN/INF。

PHP 7.4 升级到 8.1 后报错,核心不是“能不能跑”,而是“哪些地方被新规则拦住了”。PHP 8.1 加强了类型安全、废除了旧函数、收紧了错误处理,很多过去能“蒙混过关”的写法,现在直接抛出 TypeError、Fatal error 或 Deprecated。解决的关键是定位高频雷区,逐类击破,而不是盲目改全量代码。
字符串与 NULL 参数处理(最常见白屏原因)
PHP 8.1 对 `str_contains()`、`explode()`、`htmlentities()`、`strlen()` 等函数传入 `null` 零容忍,会立即报 `TypeError: ... expects string, null given`。
典型场景:模板中输出未初始化变量、数据库字段为 NULL 时直接拼接、表单未提交字段未判空就调用字符串函数。
- 所有涉及字符串操作的变量,先用 isset() 或 is_string() 做兜底,例如:
str_contains($name ?? '', 'admin')或is_string($data) ? explode(',', $data) : [] - 在 FastAdmin/ThinkPHP5.0 中,重点检查
Template.php的parseVarFunction方法,对传入函数的参数强制转字符串:(string)$value - 全局搜索
strlen(、strpos(、str_replace(等,确认左侧变量非 null —— 不要依赖静默转换
废弃函数与语法变更(必改项)
PHP 8.1 彻底移除 `mysql_*`、`create_function()`、`each()`;同时禁用花括号下标访问($str{$i})、限制命名参数混用、要求三元嵌套加括号。
立即学习“PHP免费学习笔记(深入)”;
-
mysql_* 全部替换为 mysqli 或 PDO:不能只改函数名,必须补上连接对象,例如
mysqli_query($conn, $sql),并确保$conn已初始化 -
create_function()改为箭头函数或匿名函数:fn($x) => $x * 2或function($x) { return $x * 2; },注意use捕获外部变量 - 把
$arr{$key}全部改为$arr[$key];mb_strpos($s, $t, round(...))中的 offset 强制转 int:(int)round(...)
错误处理与类型声明升级
PHP 8.1 将大量 Warning 升级为 TypeError/ValueError,且方法重写需严格协变(返回类型可更具体,但参数类型不能更宽)。
- 启用
error_reporting(E_ALL)并查看完整日志,不要忽略 Deprecated 提示——它们往往是 Fatal error 的前兆 - 检查所有继承关系中的方法签名:子类方法参数类型不能比父类更宽松(如父类接受
array,子类不能只接受string[]) - JSON 处理要显式处理 NaN/INF:
json_encode($data, JSON_INVALID_UTF8_SUBSTITUTE)避免静默截断;前端收到 null 字段时后端应主动设默认值
扩展与依赖版本匹配
扩展不是“装上就行”,PHP 8.1 的 ABI ID 是 20200930,旧版 redis.so、gd.so 会加载失败或类找不到。
- 用
php -m | grep redis确认扩展已启用,再执行new Redis()测试实例化是否成功 - 宝塔用户请去「软件商店 → PHP 8.1 → 安装扩展」重装,切勿从 PHP 7.4 复制 .so 文件
- 更新
composer.json中的 platform 声明:"platform": {"php": "8.1.10"},再运行composer update --with-all-dependencies,强制拉取支持 PHP 8.1 的包版本



















