php7.0中字符串用==比较会触发隐式类型转换,导致"0x1a"=="26"、"123abc"==123等意外为true;应统一使用===确保类型与值均一致,或显式转换后比较。

PHP7.0 中 == 比较字符串会触发隐式类型转换
当两个操作数看起来像数字(比如 "123"、"0x1A"、"1e3"),== 会先把它们转成数字再比较。这不是 bug,是 PHP 的设计行为,但极易引发意料之外的结果。
常见错误现象:
-
"0x1A" == "26"→true(十六进制被转成十进制) -
"123abc" == 123→true("123abc"转数字时截断为123) -
"0123" == 123→true(PHP7.0 仍把带前导零的字符串当作八进制解析)
这在用户输入校验、API 参数比对、密码哈希比对等场景非常危险——你以为在比字符串,其实 PHP 在比数字。
用 === 才是真正意义上的字符串相等判断
=== 强制要求值和类型都一致,不会做任何转换。只要一个是 string,另一个不是 string,结果直接是 false。
实操建议:
- 所有明确要比较字符串内容的场景,无条件用
=== - 如果变量来源不可控(如
$_GET['token']、file_get_contents()返回值),先is_string()再用===更稳妥 - 不要依赖
==的“松散”行为来兼容不同格式——显式转换(如(string)$a === (string)$b)更清晰、更可控
示例:
"123" === 123 // false(类型不同) "123" === "123" // true "0123" === "123" // false(字面量不同)
数字字符串比较的特殊陷阱:"0" 和空值
"0" 是合法字符串,但它在 == 下和多种“假值”相等,比如 0、false、null、空数组 [],甚至空字符串 ""(仅在 PHP7.0+ 中 "0" == "" 为 false,但 "0" == false 仍是 true)。
这导致常见误判:
-
if ($_POST['id'] == 0)→"0"、"00"、"0e123"都会进入分支 -
empty($_POST['token'])对"0"返回true,但你可能只是想排除空字符串
正确做法:
- 判断是否为非空字符串:用
strlen($s) > 0或$s !== "" - 判断是否等于数字字符串
"0":直接$s === "0" - 若真需数值比较,先
filter_var($s, FILTER_VALIDATE_INT)校验合法性,再转整型
PHP7.0 兼容性提醒:八进制字符串解析仍未废弃
PHP7.0 没有禁用前导零字符串的八进制解析,所以 "0123" == 83 成立(0123 八进制 = 十进制 83)。这个行为在 PHP8.0+ 中已被弃用警告,但在 7.0 环境下仍是静默生效的。
这意味着:
-
"00" === "0"→false(字符长度不同) -
"00" == 0→true("00"转数字是0) -
"010" == 8→true(八进制010= 十进制8)
最稳妥的方式始终是:不依赖自动转换,用 ===,或显式调用 strcmp() / hash_equals()(后者防时序攻击,适合敏感值)。
真正容易被忽略的点是:即使你知道 === 安全,也会在条件嵌套或默认值兜底时手滑写回 ==——建议在项目中启用 PHPStan 或 Psalm,配置规则强制检查字符串比较操作符。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











