php 8.1 中应避免向 strlen 或 mb_strlen 传入非字符串值,需用 ?? 和 is_string() 兜底校验;统一使用 mb_strlen($str, 'utf-8') 并确保 mbstring 已启用;清理隐藏字符并双重校验字符数与字节数。

PHP 8.1 判断字符串长度不报错,关键不是“怎么避免”,而是**别让非法值进到 strlen 或 mb_strlen 里**。这两个函数本身不会抛出 TypeError(PHP 8.1+ 对 null/非字符串传参会返回 null 或触发 Warning),但直接用会导致逻辑错误、静默失败或后续崩溃。
确保输入是合法字符串
用户输入、API 参数、数据库读取结果常为 null、int、array 或未定义键。不能假设 $_POST['name'] 一定存在且是字符串。
- 用空合并操作符兜底:
$str = $_POST['name'] ?? ''; - 再做类型校验:
if (!is_string($str)) { /* 拒绝或转换 */ } - 组合写法更安全:
$len = is_string($str) ? mb_strlen($str, 'UTF-8') : 0;
统一用 mb_strlen() + 显式编码
不用 strlen() 处理含中文、emoji 的内容——它返回字节数,不是用户感知的“长度”。PHP 8.1 中 mb_strlen() 仍要求第二个参数明确指定编码,否则可能 fallback 到过时的默认值(如 ISO-8859-1)。
- 必须写全:
mb_strlen($str, 'UTF-8'),别省略第二个参数 - 确认
mbstring扩展已启用:extension_loaded('mbstring'),否则直接 Fatal Error - 开发环境开启全部错误报告:
error_reporting(E_ALL),让 Warning 显形(比如传了 null)
提前清理隐藏字符和编码污染
看似正常的字符串可能含零宽空格(\xe2\x80\x8b)、BOM、软连字符等不可见字符,导致 mb_strlen() 结果比预期大,校验失败。
- 用
mb_convert_encoding($str, 'UTF-8', 'UTF-8')强制标准化并剔除非法序列 - 清除常见控制字符:
preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $str) - 调试时用
bin2hex($str)看原始字节,快速定位异常
数据库入库前加双重长度防护
字段定义是 VARCHAR(50),不代表任意 50 字符都能存——utf8mb4 下一个 emoji 占 4 字节,50 个 emoji 就是 200 字节。只校验字符数不够保险。
- 先算字符数:
$charLen = mb_strlen($str, 'UTF-8'); - 再估算最大字节数:
$maxBytes = $charLen * 4;(utf8mb4 场景) - 对照表字段真实字节上限(如
VARCHAR(50)+ utf8mb4 → 最多 200 字节)做判断
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











