PHP 7.2 判断字符串是否含不可见字符,需对比 strlen() 与 mb_strlen() 结果差异,再通过 bin2hex 定位异常字节,最后用自定义 cleanInvisibleChars 函数清除 BOM、零宽空格等 Unicode 控制符。

PHP 7.2 判断字符串是否含不可见字符,关键不是“单纯判断长度”,而是识别长度异常背后的隐藏字符干扰。因为 strlen() 本身就会把不可见字符(如零宽空格、BOM、控制符)算进去——它返回的是字节数,不是“人眼可见的长度”。
所以真正要做的,是:
✅ 检测是否存在不可见字符
✅ 理解为什么 strlen() 和语义长度不一致
✅ 给出可落地的排查与清洗步骤
一、快速检测字符串是否混入不可见字符
用两个函数对比是最直接的方法:
$input = $_POST['content'] ?? '';
$byteLen = strlen($input);
$charLen = mb_strlen($input, 'UTF-8');
if ($byteLen !== $charLen) {
// 极大概率含多字节不可见字符(如 BOM、零宽空格 U+200B、软连字符等)
}更进一步定位原始字节:
echo bin2hex($input); // 查看十六进制序列 // 常见不可见字符对应字节: // U+FEFF (BOM) → ef bb bf // U+200B (零宽空格) → e2 80 8b // U+00AD (软连字符) → c2 ad // \r → 0d, \n → 0a, \t → 09
二、常见不可见字符类型及 PHP 7.2 下的识别方式
| 字符类型 | Unicode 码点 | UTF-8 字节 |
strlen() 计为 |
mb_strlen(...,'UTF-8') 计为 |
trim() 是否清除 |
|---|---|---|---|---|---|
| 空格、\t、\n、\r | U+0020 等 ASCII 控制符 | 1 字节 | ✅ 计入 | ✅ 计入(但 trim() 可清) |
✅ |
| UTF-8 BOM | U+FEFF | ef bb bf |
✅ 计入(3 字节) | ✅ 计入(1 码点) | ❌(trim() 默认不处理) |
| 零宽空格 | U+200B | e2 80 8b |
✅ 计入(3 字节) | ✅ 计入(1 码点) | ❌ |
| 零宽非连接符 | U+200C | e2 80 8c |
✅ 计入 | ✅ 计入 | ❌ |
| 软连字符 | U+00AD | c2 ad |
✅ 计入(2 字节) | ✅ 计入(1 码点) | ❌ |
⚠️ 注意:
trim()默认只清"\t\n\r\0\x0B"和空格,对上面带U+的 Unicode 不可见字符完全无效。立即学习“PHP免费学习笔记(深入)”;
三、PHP 7.2 实用清洗方案(兼容且无需 intl 扩展)
function cleanInvisibleChars($str) {
if (!is_string($str)) return $str;
// 1. 剥离 UTF-8 BOM(最常见污染源)
$str = ltrim($str, "\xEF\xBB\xBF");
// 2. 清除 ASCII 控制字符(不含空格、tab、换行等常规空白)
$str = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $str);
// 3. 清除常见 Unicode 格式/零宽字符(覆盖 U+200B–U+200F, U+202A–U+202E, U+FEFF)
$str = preg_replace('/[\x{200b}-\x{200f}\x{202a}-\x{202e}\x{feff}]/u', '', $str);
return $str;
}
$clean = cleanInvisibleChars($input);
if (mb_strlen($clean, 'UTF-8') === 0) {
echo "清洗后为空 —— 原输入实质为不可见字符";
}✅ 此方案在 PHP 7.2 完全可用,不需要 intl 或 grapheme_* 函数。
四、判断“是否真为空”的安全逻辑(业务推荐)
别再只写 empty($input) 或 !$input:
function isSemanticallyEmpty($str) {
if (!is_string($str)) return true;
$clean = cleanInvisibleChars($str);
return trim($clean) === '';
}
// 使用示例
if (isSemanticallyEmpty($_POST['nickname'] ?? '')) {
throw new InvalidArgumentException('昵称不能为空(请勿粘贴不可见字符)');
}这样既防用户粘贴 AI 生成内容带零宽空格,也防 Excel 复制、富文本编辑器导出污染。
不复杂但容易忽略。



















