php 8.1起内置函数传null触发弃用警告,需在调用前做空值检查;常见高危函数包括strlen()、array_key_exists()等;修复原则为防御性判断+类型兜底,如$s ?? ''或is_array($arr) && array_key_exists()。

PHP 7.4 升级到 8.1 后,给内置函数传 null会触发 Deprecated: strlen(): Argument #1 ($string) must be of type string, null given 这类警告(PHP 8.1 开始将该行为标记为弃用,8.2+ 升级为致命错误)。这不是偶然报错,而是语言层面对类型安全的强制收紧——很多老项目习惯性把未初始化、查询失败或可选字段设为 null,再直接塞进 strlen()、mb_strlen()、array_key_exists()、in_array() 等函数,升级后立刻暴露。
先确认哪些函数受影响
PHP 8.1 对绝大多数接受非空类型的内置函数启用了参数类型校验。常见高危函数包括:
-
strlen()、mb_strlen()、trim()、strtolower()、strtoupper()、htmlspecialchars() -
array_key_exists($key, $arr)—— 当$arr是null时 -
in_array($needle, $haystack)—— 当$haystack是null时 -
count()、is_array()、isset()虽不报弃用,但逻辑上常与 null 共存,需一并检查
核心修复原则:不传 null,先做防御性判断
不要依赖函数内部容忍 null,而要在调用前明确处理边界值。有三类典型场景和对应写法:
-
字符串操作前加空值检查:
错:strlen($user->name)
对:strlen($user->name ?? '')或!empty($user->name) ? strlen($user->name) : 0 -
数组操作前确保变量是数组:
错:array_key_exists('id', $config)
对:is_array($config) && array_key_exists('id', $config) -
数据库/外部数据返回值兜底:
错:$row = $pdo->fetch(); $len = strlen($row['desc']);
对:$row = $pdo->fetch() ?: []; $len = strlen($row['desc'] ?? '');
批量扫描与定位技巧
靠肉眼找很难清干净。推荐两个低成本动作:
- 在 php.ini 中临时开启:
error_reporting = E_ALL & ~E_DEPRECATED→ 先屏蔽弃用警告,只看Fatal error和Warning,快速定位真正崩溃点 - 用 grep 快速筛出高危调用:
grep -r "\->name)" --include="*.php" . | grep "strlen\|mb_strlen\|trim",再人工确认是否可能为 null - 对关键模型类属性加类型声明(PHP 7.4+ 支持):
private string|null $name = null;,配合 IDE 提示提前发现未判空使用
注意兼容旧逻辑的“软替换”方式
有些地方不能改业务逻辑(比如历史数据字段确实为空),又不想大改调用链,可用以下安全封装:
- 定义一个工具函数:
function safe_strlen($s): int { return is_string($s) ? strlen($s) : 0; } - 用空合并运算符统一兜底:
mb_substr($text ?? '', 0, 100) - 对配置类或 DTO,用构造器或 setter 强制初始化:
$this->title = $data['title'] ?? '';,从源头杜绝 null
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











