strcmp返回整数而非布尔值,0表示相等,负数/正数表示大小关系;需用===判断相等,敏感场景用hash_equals()防时序攻击。

strcmp 返回的是整数,不是布尔值
很多人一写 if (strcmp($a, $b)) 就以为“进了分支就代表不相等”,结果逻辑翻车。因为 strcmp 从不返回 true 或 false,它只返回整数:0、负数(如 -1)、正数(如 1)。在 PHP 的布尔上下文中,0 是 false,而任何非零值(包括 -1)都是 true —— 这直接导致“相等时跳过分支,不相等时反而可能进错分支”。
常见错误写法:
if (strcmp($user_input, 'admin')) {
// ❌ 这里会把 "admin"
<p>正确写法应显式比对返回值:</p>
- 判断相等:用
strcmp($a, $b) === 0 - 判断不等:用
strcmp($a, $b) !== 0 - 避免隐式转换,一律用严格比较
===,防止字符串或数字类型干扰
返回值大小不代表“差多少”,只表示字典序方向
strcmp 的返回值符号有意义,数值本身没有可移植性。比如 strcmp("a", "z") 在某些 PHP 版本返回 -25,另一些返回 -1,但只要它是负数,就说明第一个字符串字典序更小。C 标准和 PHP 实现都不保证具体数值,只保证:、<code>== 0、> 0 三类语义。
所以别这么写:
if (strcmp($a, $b) == -1) { ... } // ❌ 不可靠,-1 可能变成 -5 或 -127
应该写成:
if (strcmp($a, $b) 表示 <code>$a字典序小于$b-
if (strcmp($a, $b) > 0)表示$a字典序大于$b - 排序场景中可直接传给
usort回调,因为它本来就是为这个设计的
空数组、null、非字符串传入会出问题
PHP 7+ 对 strcmp 参数类型做了严格校验。如果传入 null、数组(如 $_GET['x'][])、对象或资源,会触发 TypeError 或警告(取决于错误报告级别),而不是静默转成字符串。
典型报错信息:strcmp() expects parameter 1 to be string, array given
安全做法:
- 始终确保两个参数是字符串,必要时强转:
(string)$a和(string)$b - 但注意:
(string)[]得到"Array",这可能掩盖业务逻辑错误 - 更推荐提前校验:
is_string($a) && is_string($b),否则抛异常或拒绝处理
什么时候该用 strcmp,什么时候不该用
strcmp 适合需要区分大小写、逐字节比对(比如密码哈希校验、token 验证、协议头字段匹配)的场景。但它不是万能字符串相等判断工具。
替代方案要按需选:
- 忽略大小写?用
strcasecmp(),它行为一致但不敏感 - 只比前 N 个字符?用
strncmp($a, $b, $n) - 自然排序(如 "file10.jpg" > "file2.jpg")?用
strnatcmp() - 只是判断是否相等?现代 PHP 更推荐直接用
===,语义清晰、性能略优、无类型陷阱
真正容易被忽略的一点:当你要做「恒定时间比较」防时序攻击(比如验证签名或 token),strcmp 不安全,必须用 hash_equals() —— 它的实现才是恒定时间的。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











