PHP中唯一合法的逻辑非运算符是!,它将操作数转布尔后取反,但因类型转换规则复杂(如'0'、0、null均为falsy),易导致误判,应优先使用isset()、empty()、===等严格判断方式。
PHP 里
是唯一的逻辑非运算符
PHP 没有
关键字,也不支持
(那是按位取反),唯一合法的逻辑非就是单个英文感叹号
。它作用于任意表达式,返回布尔值:
或
。
常见错误是把它和赋值或比较混用,比如写成
(少了个等号)——这实际是赋值,不是判断;或者误以为
总成立,其实
、
、
都是
,但它们彼此不全等。
总是先将操作数转为布尔值再取反,所以
是
(字符串
转布尔为
,再取反得
?不对——等等,这里容易错:实际上
是“falsy”值,
结果是
)
想判断变量是否“未定义或为空”,别只靠
,它会把
、
、
全当假——该用
或
+ 显式检查
是常见技巧:强制转布尔,等价于
,但可读性差,线上代码建议直接用类型转换
什么时候
会静默失败或行为反直觉
最典型的是对数组、对象、资源使用
。PHP 会先转布尔:
是
(空数组是 falsy),但
是
(非空数组是 truthy);而
是
(对象恒为 truthy),哪怕它没属性。
更隐蔽的是浮点数:
是
,但
也是
;而
是
(非零即 truthy)。别指望它做数值精度判断。
立即学习
“
PHP免费学习笔记(深入)
”;
不要用
,直接写
更清晰、不触发隐式转换
是惯用法(
相等时返回 0 → 取反为
),但可读性低,建议改用
函数返回
时,
会是
,但如果函数本意是返回 0 或 false 表示失败,这个判断就不可靠
和
搭配使用的安全写法
单独用
做判空或存在性检查,90% 的场景其实该换成严格比较。比如验证 API 返回是否成功:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
这段代码在
时也会进分支(因为
返回 PHP
,
是
),但你本意可能是“解码失败”。
检测 JSON 解码失败:用
检测数组键存在且非空:用
,而不是
(后者会放过
)
函数返回布尔值时才放心用
:如
、
—— 这些文档明确说返回 bool
性能和短路逻辑里
的真实影响
本身开销几乎为零,但它常出现在条件表达式中,影响短路行为。例如:
,如果
为 truthy,
就不会执行;但如果写成
,效果一样,只是多一次比较。
真正要注意的是嵌套否定:
等价于
,但前者难读、易出错,也增加解析负担(虽微乎其微)。
避免双重否定,尤其在复杂条件里,人脑不擅长逆向推导
不改变操作数本身,它只是求值,所以
中的自增仍会发生(先取
当前值取反,再加 1)
在循环条件里慎用
:它依赖内部指针状态,不如用
返回值直接判断
逻辑非看着简单,但 PHP 的松散类型让
的结果高度依赖上下文。真要写稳,就得清楚每个操作数在布尔上下文里的确切表现——而不是凭感觉猜。
!not~!truefalseif ($a = !true)!$a === false!null!0!''true!!'0'false'0'falsetrue'0'!'0'true!$var0'0'falseempty()isset()!!$var(bool) $var!!![]true![1]false!new stdClass()false!0.0true!(-0.0)true!1e-10false!is_null($x)$x !== null!strcmp($a, $b)strcmptrue$a === $bnull!some_function()true!===!$res = json_decode($json, true);
if (!$res) { ... }$json = 'false'json_decode('false')false!falsetruejson_last_error() === JSON_ERROR_NONEisset($arr['key']) && $arr['key'] !== ''!empty($arr['key'])'0'!!file_exists($path)!is_dir($dir)!!if (!$a && $b())$a$b()if ($a == false && $b())if (!(!$a || !$b))if ($a && $b)!!$x++$x!feof()fgets()!