在PHP中,当遇到某些错误时,您可以通过调用or die
来退出错误,例如:
$handle = fopen($location, "r") or die("Couldn't get handle");
使用die()
不是处理错误的好方法。我宁愿返回一个错误代码,以便父函数可以决定做什么,而不仅仅是不正确地结束脚本并向用户显示错误。
但是,当我尝试将or die
替换为or return
时,PHP显示错误,如下所示:
$handle = fopen($location, "r") or return 0;
为什么or die()
有效,而or return 0
无效?
答案 0 :(得分:26)
我想感谢你提出这个问题,因为我不知道你不能在PHP中执行or return
。当我测试时,我和你一样惊讶。这个问题给了我一个很好的借口,可以在PHP的内部进行一些研究和游戏,这实际上非常有趣。但是,我不是PHP内部的专家,所以以下是PHP内部的外行人看法,尽管我认为它相当准确。
or return
无效,因为return
并未被视为"表达"语言分析器 - 简单。
关键字or
在PHP语言中定义为名为T_LOGICAL_OR
的标记,并且似乎定义的唯一表达式看起来像this:
expr T_LOGICAL_OR { zend_do_boolean_or_begin(&$1, &$2 TSRMLS_CC); } expr { zend_do_boolean_or_end(&$$, &$1, &$4, &$2 TSRMLS_CC); }
不要担心大括号中的位 - 只是定义了实际的"或"处理逻辑。你留下的是expr T_LOGICAL_OR expr
,它只是说它是一个有效的表达式,有一个表达式,后跟T_LOGICAL_OR
标记,后跟另一个表达式。
解析器也定义expr
,正如您所期望的那样。它可以是r_variable
,只是意味着它是您允许阅读的变量,或expr_without_variable
,这是一种表达表达式的奇特方式用其他表达方式构成。
您可以执行or die()
,因为语言构造die
(不是函数!)及其别名exit
都由标记T_EXIT
表示,{{1被视为有效T_EXIT
,而expr_without_variable
语句 - 令牌return
- 则不是。
现在,为什么T_RETURN
被视为表达式而T_EXIT
不是?老实说,我不知道。也许这只是一个设计选择,只是为了允许您提出的T_RETURN
结构。以前它被广泛使用的事实 - 至少在教程之类的东西,因为我不能说出大量的生产代码 - 似乎暗示这可能是一个有意的选择。您必须要求语言开发人员确切知道。
所有这些都说明了,这不重要。虽然or die()
构造在几年前的教程(见上文)中似乎无处不在,但它并不是真正推荐的,因为它是"聪明的代码"的一个例子。 or die()
不是自己的构造,而是使用 - 有些人可能会说滥用 - 使用or die()
运算符的两个副作用的技巧:
or
,则不执行第二个操作数(or
之后的位),因为如果一个操作数是{{1在TRUE
表达式中,它们都是。有些人认为这种技巧是不利的,因为程序员更难阅读但只能在源代码中保存一些空格字符。由于程序员时间昂贵,磁盘空间便宜,你可以看出为什么人们不喜欢这样。
相反,您应该通过将代码扩展为完整的TRUE
语句来明确表达您的意图:
or
您甚至可以在if
语句中执行变量赋值。有些人仍然认为这是不可读的,但大多数人(包括我自己)不同意:
$handle = fopen($location, "r");
if ($handle) {
// process the file
} else {
return 0;
}
最后一件事:按照惯例,将if
作为状态代码返回表示成功,因此您可能希望返回一个不同的值来表示您无法打开该文件。
答案 1 :(得分:0)
我也偶然发现了一次。我能找到的就是:
https://bugs.php.net/bug.php?id=40712
请看下面的评论:
这不是错误
我在文档中搜索过,我认为这是因为return 0
是一个陈述,而die()
本质上是一个表达式。您无法运行$handle = return 0;
,但$handle = fun();
是有效代码。
关于错误处理,我建议使用自定义代码或使用自定义处理程序和触发器。例如,后者为described here。
答案 2 :(得分:0)
返回相当特殊 - 它不能像函数一样,因为它是退出函数的工具。想象一下:
if(1==1) return(); // say what??
如果是这样的话, return 必须是一个执行"双退出"的功能,不仅留下自己的范围,而且留下来电者,太。因此,回归不仅仅是一种表达方式,它根本无法以这种方式运作。
现在理论上,return可以是一个表达式,其评估为(假设)false,然后退出函数;也许以后的php版本会实现这个。
同样的事情适用于转到,这将成为一个后备的魅力;是的,后备是必要的,并且经常使代码可读,所以如果有人抱怨"聪明的代码" (这当然是一个好点)也许PHP应该有一些"官方"做这样的事情的方式:
connectMyDB() fallback return false;
像尝试......抓住的东西,更重要的是。就个人而言,我对#34;或者#34;感到非常高兴。做这项工作,因为它与英语语法配合得很好:"连接或报告失败"。
TLDR:你绝对正确:return,goto,break - 它们都不起作用。容易理解为什么但仍然很烦人。