区分大小写用 strcmp(),忽略大小写用 strcasecmp();二者返回整数而非布尔值,需避免直接用于 if 判断;utf-8 字符串须用 mb_strcmp() 或 mb_strtolower()+strcmp() 组合;=== 仅判字节相等,不适用字典序比较。

strcmp() 和 strcasecmp() 怎么选
区分大小写时用 strcmp(),忽略大小写用 strcasecmp()。它们返回整数:0 表示相等,负数表示第一个字符串小,正数表示第一个字符串大——不是布尔值,别直接用在 if ($a == $b) 里。
- 常见错误:把
strcmp()当作返回 true/false 的函数,结果if (strcmp($a, $b))在不等时反而进入分支(因为返回 -1 或 1,都为真) - 使用场景:用户登录校验、配置项开关判断、字典序排序前的比较
- 注意:这两个函数按字节比较,对 UTF-8 多字节字符(比如中文、emoji)不可靠,会截断或错位
中文或 UTF-8 字符串怎么安全比较
必须用 mb_strcmp()(PHP 8.2+)或退而求其次用 mb_strtolower() + strcmp() 组合,否则 strcmp() 可能把一个中文字符拆成两三个字节比,结果完全不可预测。
- PHP 8.2+ 直接用:
mb_strcmp($a, $b, 'UTF-8'),第三个参数指定编码,不传可能用默认 locale,行为不稳定 - 低版本 PHP:先转小写再比,
strcmp(mb_strtolower($a, 'UTF-8'), mb_strtolower($b, 'UTF-8')),但注意性能损耗和某些语言(如土耳其语)的特殊规则 - 别用
==或===做“字典序”比较——它们只判相等,不提供大小关系
松散比较(==)和严格比较(===)的坑
== 会触发类型转换,字符串比较时极容易出事;=== 是字节级全等,但依然不管编码,也不管 Unicode 归一化。
- 典型翻车:
"0" == ""返回 true(字符串转数字后 0 == 0),"1" == "01"也 true -
===虽然不转类型,但"café" === "cafe\u{301}"是 false(组合字符 vs 预组字符),实际内容一样却判不等 - 结论:业务中需要“相等”就用
===(确保字节一致);需要“字典序”就用strcmp()或mb_strcmp();别混用
性能差异大吗?什么时候该换方案
纯 ASCII 场景下 strcmp() 比 === 慢约 2–3 倍,但差别在纳秒级,日常几乎感知不到;真正拖慢的是 mb_* 系列函数,尤其长文本+多语言时,开销明显上升。
立即学习“PHP免费学习笔记(深入)”;
- 高频调用(如循环内比较)且确定是英文/数字:优先
===判相等,strcmp()判顺序 - 涉及用户输入、数据库字段、API 返回值:默认走
mb_strcmp()或至少mb_strtolower()+strcmp(),别省那点性能赌输入干净 - 注意 mbstring 扩展是否启用:
extension=mbstring必须在 php.ini 里打开,否则mb_*函数直接报 fatal error
mb_strcmp() 遇到 GBK 字节流照样崩,得先 mb_detect_encoding() 或统一转码。











