===要求值和类型均相同,==会触发类型转换;如"1"==1为true但"1"===1为false,权限校验、函数返回值判断等场景必须用===避免类型陷阱。

PHP中===和==的区别到底在哪
严格比较不是“多加个等号”就完事,而是彻底绕过PHP的类型转换逻辑。用==时,"1"、1、true全会被判为相等;而===要求值和类型都一致,"1" === 1直接返回false。
常见错误现象:用户登录后校验$_SESSION['role'] == 'admin',结果传入数字1(比如数据库里存的是tinyint)也能通过——因为1 == 'admin'会把字符串转成数字再比,结果是1 == 0?不,其实是'admin'转为0,所以1 == 0为false……等等,这反而“没绕过”,说明你根本没理清转换规则。别猜,直接用===省心。
- 字符串
"0"和整数0:用==是true,用===是false -
null和空字符串"":用==是true,===是false - 浮点数
0.0和整数0:同上,类型不同就false
什么时候必须用===而不是==
核心判断标准:只要变量来源不可控,或类型本身可能变化,就该用严格比较。典型场景包括数组键存在性检查、函数返回值判断、配置开关解析。
例如in_array()默认用松散比较,in_array(0, ["a", "b"])居然返回true——因为"a"被转成0。解决方法是显式传第三个参数:in_array(0, ["a", "b"], true)。
立即学习“PHP免费学习笔记(深入)”;
- 检查
strpos()是否找到子串:必须写strpos($str, 'x') !== false,不能用!= false,否则strpos返回0(开头匹配)会被当成false - 解析JSON后判断字段是否存在:
isset($data['id'])安全,但$data['id'] == 0可能误判,应改用$data['id'] === 0或先is_int()校验 - 处理
filter_var()结果:它可能返回false或0,用===才能区分验证失败和合法值为零
===在类型混合场景下的实际表现
PHP不会帮你“纠正”类型,它只做字面匹配。这意味着你得自己确保比较前两边类型一致,否则===永远不成立。
比如从$_GET取参数$_GET['limit'],它永远是字符串。想和整数10严格比较?先转类型:(int)$_GET['limit'] === 10,或者用filter_var($_GET['limit'], FILTER_VALIDATE_INT) === 10。
-
0 === "0"→false(不用指望自动转换) -
0 === (string)0→false((string)0是"0") -
0 === intval("0")→true(显式转整型) - 用
is_numeric()不能替代===,它只判断能否转数字,不参与比较逻辑
性能和兼容性影响几乎可以忽略
严格比较比松散比较略快,但差距在纳秒级,实际项目中感知不到。PHP所有版本(5.3+到8.x)对===行为完全一致,不存在兼容性问题。
真正要小心的是开发习惯:一旦养成写==的肌肉记忆,遇到关键逻辑(如权限校验、支付金额比对)就容易漏掉类型陷阱。与其事后补测,不如从第一个if开始就用===。
最常被忽略的一点:函数返回值文档未必标明类型。比如array_search()查不到时返回false,查到0位置也返回0——这两个0和false必须用===才能准确区分。不看源码、不查手册、只靠==试,迟早踩坑。











