php 中 "!print("1") || 1" 的意外行为

问题描述

示例 1:

if(!print("1") || 1){
   echo "a";
}else{
   echo "b";
}

输出

1b

示例 1 打印的是“1b”而不是“1a”。根据我的说法,在解决 !print("1") 之后,如果最终条件应该是 if(0 || 1)

但是示例 2 正在打印“1a”。

示例 2:

if((!print("1")) || 1){
   echo "a";
}else{
   echo "b";
}

输出

1a

你能详细说明为什么第一个语句中的 or 条件不起作用。

解决方法

这里的关键是要意识到 print 不是函数,并且不接受括号中的参数 - 括号不是可选的,它们根本不是语法的一部分。

当您编写 print("1"); 时,打印语句只有一个参数,即表达式 ("1")。这当然只是 "1" 的另一种书写方式 - 您可以添加任意数量的括号并且不会更改值。

因此,当您编写 print("1") || 1 时,要打印的参数是表达式 ("1") || 1。该表达式使用 PHP 的类型杂耍规则计算为 true || true,即 true。然后它被传递给 print 并且 - 完全巧合的是你试图打印的 - 是类型杂耍到字符串 "1"

print 语句随后被视为返回 true 的表达式,而 ! 将其设为 false,因此 if 语句不会运行。

这是一个很好的理由,不要在 printrequireinclude 等关键字旁边使用括号 - 它们给人的错误印象是“附加”了关键字参数。