"&&"和"and"之间的区别:操作符优先级和短路求值。

6
我正在阅读php.net的运算符优先级部分,看到了这个例子,它说:
$a = 1;
$b = null;
$c = isset($a) && isset($b);
$d = ( isset($a) and isset($b) );
$e = isset($a) and isset($b);
var_dump($a, $b, $c, $d, $e);
//Result:
int(1)
NULL
bool(false)
bool(false) <== I get this
bool(true)  <== I do not get this

我在我的代码中使用了相当多的调试和详细的print(_r)语句来跟踪代码的执行过程。因此,我在代码之间使用$debug and print_r($dataArray)$verbose and print "Updating dataArray\n"作为单独的语句,这样我就可以控制这些print(_r)语句的输出。这种做法源于我在BASH中编写大量[[ $condition ]] && { #Do if true } || { #Do if false }的经验。在BASH中,我知道它们被短路了,并利用这一点编写了很多简单的一行代码。
现在我发现这种写法(写$verbose and print)正慢慢地渗透到我的if语句中。我知道这不是推荐的做法,而且可能会对我造成伤害。然而,我确实想要掌握这种技能,因为我喜欢写这样的一行代码,并希望将其作为我的个人风格使用。
所以我的问题是:
  1. &&and哪个是短路的运算符?
  2. 手册上说&&优先于and,但是否有人可以通过混合短路运算符的特性/功能/特征和操作符优先级来说明这一点。(基本上是优先级和短路混合)
请详细说明运算符的短路和返回值特性。
PS: 1. 我希望这些运算符的关联性是相同和直观的,但如果你知道任何怪异的地方,请告诉我。 PS: 2. 如果你仍然感觉需要警告我这种做法的危险性,请举例说明。

编辑:我曾经用简单的$var = mysql_(...) or die()代码,将其中的or替换为||后,我发现使用||&&运算符比使用andor运算符更加麻烦。 代码根本就不起作用!在我看来,前一种结构将$var的返回值赋值为TRUEFALSE,这会导致所有顺序使用$var的行为产生警告/错误/意外行为。而后一种结构首先将mysql_(...)的结果分配给$var,然后评估=die的复合体。
这是一个好的教训,我最好 1. 开始使用PDO/mysqli并自己处理错误 2. 在编写所谓的个人风格的东西之前三思。
//自我提示:不要在编写另一种脚本/解释语言的代码时使用一种语言的经验,每种语言都是独特的,都有自己的怪癖和缺陷,这很悲哀 *叹气*


可能是参考 - PHP中这个符号代表什么?的重复问题。 - Gordon
@Gordon:感谢您提供的参考资料。我查看了列表,虽然有几个问题似乎回答了部分问题(例如优先级,我已经知道),但是我认为运算符的短路特性以及它们的优先级没有详细讨论。 - Sudhi
相关链接:https://dev59.com/JXA75IYBdhLWcg3wkaCA - James P.
不用谢。这个链接可能对你有用。我不确定通过Google翻译它会有多易读,但代码基本上是清晰的:http://www.alsacreations.com/tuto/lire/676-gestion-erreurs-mysql-php-or-die.html - James P.
谢谢@James。我将来会使用PDO编写代码,但现在我已经用||(和&&)替换了所有的or(和and)。 - Sudhi
显示剩余3条评论
1个回答

7
代码
$e = isset($a) and isset($b);

被解析的内容与

($e = isset($a)) and isset($b);

因此,由于isset($a)和赋值确定的原因,$e是true,与评估isset($b)无关。

@Felix:你能否请写/解释/详细说明一下PHP中的短路吗?我特别关心在短路之后生成的返回值。 - Sudhi
1
@Sudhi:我不明白你想让我写什么。所有这些运算符(&&||andor)都是短路的...返回值始终是布尔值。 - Felix Kling
如果在同一表达式中混合使用 && 和 ||,那么会发生什么?是先计算 &&,还是严格按照从左到右的顺序进行评估? - David Spector

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接