PHP弱类型指自动类型转换而非不检查类型,易致安全漏洞;==会类型转换而===严格比较,如"123abc"==123为true,科学计数法字符串"0e123456"=="0e789012"也为true;防御须用===、filter_var()等严格校验。

PHP弱类型不是“不检查类型”,而是在比较、运算或函数调用时,自动按规则转换类型再继续执行,而不是报错中断。它让代码写起来更省事,但一旦逻辑依赖类型一致性(比如权限校验、密码比对、输入过滤),就容易出错甚至被绕过。
== 和 === 的行为差异直接暴露弱类型机制
这是最常踩坑的点:PHP 用 == 比较时会先尝试类型转换,=== 才真正“看值又看型”。
-
"123abc" == 123→ true(字符串开头是数字,截取转为整数) -
"abc123" == 0→ true(开头非数字,整体转为 0) -
true == "anystring"→ true(非空字符串转为true) -
null == false、0 == ""、0 == "0"全部为 true - 而所有上面这些,换成
===全是 false
函数参数松散性:传数组进 md5() 不报错却返回一致结果
很多内置函数声明要求字符串,但 PHP 不强制拦截非字符串输入,而是静默处理——这正是弱类型的典型副作用。
-
md5([])和md5([1,2])都触发Warning: md5() expects parameter 1 to be string, array given,但返回值都是false(或空字符串,取决于版本),导致md5([]) == md5([1,2])成立 -
strcmp("a", [])返回null,而null == 0是 true,可能绕过条件判断 -
in_array("0", [0, 1, 2], true)是 false,但去掉第三个参数(false)就变成 true,因为"0" == 0
科学计数法字符串比较:"0e123456" == "0e789012" 为 true
这不是 bug,是 PHP 把以 0e 开头、后面全为数字的字符串当作科学计数法解析的结果——都等于 0。
立即学习“PHP免费学习笔记(深入)”;
-
"0e123456" == "0e789012"→ true(两者都被转成浮点数0.0) -
"0e123abc" == 0→ true(非法科学计数法,转为0) -
"0x123" == 291→ true(十六进制字符串被识别并转为十进制) - 这种行为在哈希比对、token 校验、验证码逻辑里极易被利用
真正危险的不是“能转换”,而是转换规则不直观、不透明,且发生在你没写任何转换代码的地方。哪怕你用 is_string() 做了前置检查,只要后续用了 == 或传给了松散函数,就可能失效。防御核心只有一条:该用 === 的地方绝不偷懒写 ==,该校验类型的函数(如 filter_var()、is_int())别跳过,尤其在安全敏感路径上。



















