应先拼接再用 strlen() 测总字节数,而非累加各段长度;需按字节限长选 strlen(),按字符数限长选 mb_strlen($str, 'UTF-8')。

拼接后字符串长度用 strlen() 直接算,别先拼再测
PHP 中判断拼接后字符串长度,最直接的方式是先完成拼接,再用 strlen() 获取字节数。注意:它统计的是字节长度,不是字符个数(尤其对 UTF-8 中文会出错)。如果你只是校验总长度是否超限(比如数据库字段、API 参数限制),strlen() 是正确选择;如果要按“用户感知的字符数”判断(如显示宽度、输入计数),得换 mb_strlen($str, 'UTF-8')。
常见错误是写成这样:
$len = strlen($a) + strlen($b) + strlen($c); // 错!忽略编码开销、空格、分隔符
实际拼接中可能含空格、换行或连接符(如 "$a-$b"),直接加各段长度会漏掉这些额外字节。
strlen() 和 mb_strlen() 在拼接场景的关键区别
拼接字符串时选哪个函数,取决于你的长度定义目标:
立即学习“PHP免费学习笔记(深入)”;
-
strlen()返回字节数:适合底层限制(如 MySQLVARCHAR(255)按字节存、HTTP header 长度限制) -
mb_strlen($str, 'UTF-8')返回 Unicode 字符数:适合前端展示、用户输入提示(如“还剩 10 个字”) - 若没指定编码,
mb_strlen()可能用默认内部编码(由mb_internal_encoding()决定),线上环境不一致易导致结果漂移 - 中文、emoji 等多字节字符在 UTF-8 下占 2–4 字节,
strlen()会高估“可读字符数”
拼接前预估长度?小心中间变量和类型转换陷阱
有人想“不拼接就预估”,比如:strlen($a . $sep . $b) 改成 strlen($a) + strlen($sep) + strlen($b)。这仅在确定所有变量都是字符串且无隐式转换时才安全。
以下情况会导致预估失败:
-
$a是int或null:strlen(null)返回 0,但(string)null是空字符串,而null . "x"会转成"x"—— 表面看没问题,但strlen(0)是 1,0 . "x"是"0x",长度为 2 -
$sep是数组或对象:直接strlen()触发警告,返回 0;但拼接时会触发Array to string conversion警告,结果为"Arrayx" - 使用
sprintf()或vsprintf()拼接时,格式符本身不占长度,但替换值可能带不可见字符(如\r\n)
真实接口参数拼接长度检查的推荐写法
例如构造签名字符串:$signStr = $appId . $timestamp . $nonce . $data;,要求总长 ≤ 512 字节:
$signStr = $appId . $timestamp . $nonce . $data;
if (strlen($signStr) > 512) {
throw new InvalidArgumentException('Sign string too long: ' . strlen($signStr) . ' bytes');
}
关键点:
- 一定在拼接完成后立刻测,避免中间变量被覆盖或修改
- 错误信息里输出实际字节数,方便定位哪次调用越界
- 如果
$data来自 JSON 编码,注意json_encode()默认加空格和换行(用JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES控制) - 不要用
mb_strlen()替代,除非你确认服务端校验逻辑也按字符数而非字节
真正容易被忽略的是:不同 PHP 版本对超长字符串的处理差异不大,但某些 SAPI(如 CGI/FPM)对单个请求体总长有限制,拼接后的长度只是其中一环——别只盯着这一处。











