在PHP中使用'or die()'停止错误

18

在PHP中,我经常看到以下代码:

$result = mysql_query($query) or die();

我来自Python,我知道这应该可以工作,因为or在布尔环境下返回第一个值如果它是真的,否则返回第二个值(请参见此文)。

但是当我在PHP中尝试上述技巧时,却无法奏效,例如在另一个上下文中:

$name = "John Doe";
echo $name or "Anonymous";
or不会返回第一个值("John Doe"),它会返回1。
为什么这在mysql_query()结果中有效,但在其他情况下无效?在mysql_query()情况下使用它是否不好(忽略我没有向用户返回有用的错误信息)?
7个回答

33
在PHP中,变量赋值(等号)和函数在or运算符中的优先级都高于or。这意味着函数会先执行,然后将函数的返回值用于or比较。反过来,当你使用两个值/变量与or运算符一起时,它首先比较这两个值,然后返回一个布尔值。
因此,在这个例子中,评估的顺序是:
$result = mysql_query($query) or die();
  1. mysql_query($query)
    对于DQL查询(例如SELECT),返回结果集;对于DDL、DML或DCL查询(例如CREATEDROPINSERTUPDATEDELETEALTER),返回布尔值。

  2. $result = mysql_query($query)
    将执行此查询的结果分配给变量$result

  3. $result /* = ... */ or die();
    如果它是结果集或true,则被认为是true(又称“truthy”),因此满足or条件,并在此处结束语句。否则脚本将会die()


echo是一种语言结构,因此实际上不会返回值,所以在进行or比较之前不会像函数一样运行。

由于$name or "Anonymous"始终为真,因为字符串"Anonymous"是非空的,因此为真,echo隐式地将true转换为1,因此输出为1

在这个例子中,评估顺序是:

$name = "John Doe";
echo $name or "Anonymous";
  1. $name = "John Doe";
    这很简单 - 给变量$name赋值为字符串John Doe

  2. $name or "Anonymous"
    PHP发现变量$name包含字符串John Doe,所以实际上被评估的是以下内容:

  3. "John Doe" or "Anonymous"
    由于至少有一个字符串不为空,所以它被认为是真值(truthy),条件得到满足。这个求值会返回true

  4. echo true /* $name or... */;
    true转换为1并打印数字1。


那我猜这将与printf等打印函数一起工作,或者是同样的问题,因为它会产生输出?它是一个函数,所以应该可以工作,对吗? - Fidi
所以=是一个函数,但or是一个运算符?我本来以为=也是一个运算符。此外,这是错误的。die()函数在or之前不会被执行。 - rjmunro
@faileN:没错。printf()是一个返回打印字节数的函数,所以它会类似于mysql_query()调用运行。 - BoltClock
@rjmunro:=是赋值运算符。它不是一个函数,但在PHP中,它or运算符具有更高的优先级。我在我的编辑中进行了澄清。 - BoltClock

2
为什么or会返回任何内容呢?or是一个普通的布尔运算符。当$a$b中有一个为true时,$a or $b的结果为true,否则结果为false||or之间的区别在于,or的运算优先级更低,甚至比=还要低。这就是为什么……(缺少上下文,无法翻译完整)
$result = mysql_query($query) or die();

是等同于

($result = mysql_query($query)) or (die());

相反,
$result = mysql_query($query) || die();

等同于

$result = (mysql_query($query) || die());

在您的情况下
echo $name or "Anonymous";

获取

(echo $name) or ("Anonymous");

你可能正在寻找的是三元运算符:
echo $name ?: 'Anonymous';

如果你的PHP版本是5.2,那么上述代码将无法运行。请使用以下代码:
echo $name ? $name : 'Anonymous';

2

在我提出问题后不久,我就想到了原因。这与运算符优先级有关。在or之前发生=,因此:

$result = mysql_query($query) or die();

等价于:

($result = mysql_query($query)) or die();

注意:

$result = (mysql_query($query) or die());

就像在Python中一样。因此,这个:

$a = false or true;

将会把$a设置为false而不是true,这将在未来某个时刻使我感到困惑。


1

PHP 常被称为“类型转换”。换句话说:PHP 会根据当前使用情况转换任何值的类型。由于字符串将被转换为“true”值,因此您的表达式返回 true。但是 echo 想要打印一个字符串表达式,并将“true”转换为 1。在某些情况下有点烦人,但如果您知道它,也知道如何处理 ;)

顺便看看这个:http://php.net/manual/en/types.comparisons.php


1

or子句首先被评估并返回一个布尔值,该值由echo输出。如果您想要输出文本,则需要使用if/else结构,例如:

echo ($name ? $name : 'Anonymous');

4
如果你正在运行 PHP 5.3 或更高版本,可以使用 echo $name ?: "Anonymous"; 来输出名字,如果 $name 为空,则输出 "Anonymous"。 - nickf

0

这是因为echo不是一个函数,它是一种语言结构。它模仿成为一个函数,但实际上并不是 :)

我永远不会像这样使用die(),这有点粗糙。您应该适当地处理错误,而不仅仅是退出。


我说过:“忽略我没有向用户返回有用的错误信息” - 那不是问题的一部分。你错过了这个答案的整个问题所在。无论echo是否是一个函数,echo (false or true);或者printf(false or true);应该和$a = (false or true); echo $a;是一样的。 - rjmunro
@rjmunro:第一段(试图)回答您的问题。echo $name or "John Doe";应该做什么?(echo $name) or "John Doe"还是echo ($name or "John Doe")?这是一个重要的问题。因此,它很重要是函数(具有返回值)还是语言结构(没有返回值)。 - Dennis Haarbrink

0
如果你想要复制这种行为并且输出到屏幕/浏览器,你需要一个能够返回除了TRUE以外的东西的函数。printf()可以帮助你实现这个目标。
echo microtime."&lt;br&gt;";<
$str = "";
printf("%s",$str) or die();
echo "&lt;br&gt;".microtime();

如果 $str 是空的、null 或 false,将调用 die() 函数,否则脚本将继续执行。

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