在PHP中,为什么“或死()”工作,但是“或返回”不? [英] In PHP, why does "or die()" work, but "or return" doesn't?

查看:106
本文介绍了在PHP中,为什么“或死()”工作,但是“或返回”不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在PHP中,您可以通过调用或退出来处理错误,当您遇到某些错误时,如下所示:



$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

使用 die()不是很好的处理错误的方法。我宁愿返回一个错误代码,以便父函数可以决定要做什么,而不是仅仅以不合格的方式结束脚本,并向用户显示错误。



但是,当我尝试用替换或死时,PHP显示错误,如下所示:

  $ handle = fopen($ location,r)或返回0; 

为什么或die()但不是或返回0

解决方案

我要感谢你提出这个问题,因为我不知道你不能在PHP中执行或返回。当我测试它时,我感到惊讶。这个问题给了我一个很好的借口,在PHP内部做一些研究和玩耍,这实际上是很有趣的。不过,我不是PHP的内部专家,所以下面是一个外行人对PHP内部的看法,尽管我认为这是相当准确的。






或返回不起作用,因为 return 不被视为表达式语言解析器 - 简单的。



关键字在PHP语言中被定义为一个名为 T_LOGICAL_OR ,并且似乎定义的唯一表达式看起来像这个

  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 ,这是一个很好的方法,表达式可以由其他表达式。



你可以做或die()因为语言结构 die (不是函数!)及其别名 exit 都由令牌 T_EXIT T_EXIT 被认为是有效的 expr_without_variable 返回语句 - 令牌 T_RETURN - 不是。



现在,为什么 T_EXIT 被认为是一个表达式,但 T_RETURN 不是?老实说,我没有线索。也许这只是一个设计选择,只是为了允许你要求的或die()构造。事实上,它过去被广泛使用 - 至少在教程中,因为我不能说大量的生产代码 - 似乎暗示这可能是一个有意的选择。您必须要求语言开发人员知道。






所有这一切都表示,这并不重要。虽然几年前,或die()构造似乎在教程(见上文)中无处不在,但它并不是真正推荐的,因为它是聪明的代码的例子。 或die()不是自己的构造,而是使用一个技巧 - 有些可能会说滥用 - $ code的两个副作用>或运算符:




  • 在运算符优先级列表中这是非常低的,这意味着几乎每个其他表达式在它之前进行评估

  • 它是一个短路运算符,这意味着第二个操作数(之后的位)如果第一个操作数返回 TRUE ,则不执行,因为如果一个操作数在中的 TRUE 表达式,那么他们都是。



有些人认为这种诡计是不利的,因为程序员难以阅读,只能在源代码中保存几个字符的空格。由于程序员时间昂贵,磁盘空间便宜,您可以看到为什么人们不喜欢这样做。



相反,您应该明确地通过扩展您的如果语句:

  $ handle = fopen ($ location,r); 
if($ handle){
//处理文件
} else {
return 0;
}

你甚至可以在如果语句。有些人仍然觉得这是不可读的,但大多数人(我自己都包含)不同意:

  if($ handle = fopen($ location, r)){
//处理文件
} else {
return 0;
}

最后一件事:返回 0 作为状态代码指示成功,所以您可能想要返回一个不同的值,表示您无法打开该文件。


In PHP, you can handle errors by calling or die to exit when you encounter certain errors, like this:

$handle = fopen($location, "r") or die("Couldn't get handle");

Using die() isn't a great way to handle errors. I'd rather return an error code so the parent function can decide what to do, instead of just ending the script ungracefully and displaying the error to the user.

However, PHP shows an error when I try to replace or die with or return, like this:

$handle = fopen($location, "r") or return 0;

Why does or die() work, but not or return 0?

解决方案

I want to thank you for asking this question, since I had no idea that you couldn't perform an or return in PHP. I was as surprised as you when I tested it. This question gave me a good excuse to do some research and play around in PHP's internals, which was actually quite fun. However, I'm not an expert on PHP's internals, so the following is a layman's view of the PHP internals, although I think it's fairly accurate.


or return doesn't work because return isn't considered an "expression" by the language parser - simple as that.

The keyword or is defined in the PHP language as a token called T_LOGICAL_OR, and the only expression where it seems to be defined looks like 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); }

Don't worry about the bits in the braces - that just defines how the actual "or" logic is handled. What you're left with is expr T_LOGICAL_OR expr, which just says that it's a valid expression to have an expression, followed by the T_LOGICAL_OR token, followed by another expression.

An expr is also defined by the parser, as you would expect. It can either be a r_variable, which just means that it's a variable that you're allowed to read, or an expr_without_variable, which is a fancy way of saying that an expression can be made of other expressions.

You can do or die() because the language construct die (not a function!) and its alias exit are both represented by the token T_EXIT, and T_EXIT is considered a valid expr_without_variable, whereas the return statement - token T_RETURN - is not.

Now, why is T_EXIT considered an expression but T_RETURN is not? Honestly, I have no clue. Maybe it was just a design choice made just to allow the or die() construct that you're asking about. The fact that it used to be so widely used - at least in things like tutorials, since I can't speak to a large volume of production code - seems to imply that this may have been an intentional choice. You would have to ask the language developers to know for sure.


With all of that said, this shouldn't matter. While the or die() construct seemed ubiquitous in tutorials (see above) a few years ago, it's not really recommended, since it's an example of "clever code". or die() isn't a construct of its own, but rather it's a trick which uses - some might say abuses - two side-effects of the or operator:

  • it is very low in the operator precedence list, which means practically every other expression will be evaluated before it is
  • it is a short-circuiting operator, which means that the second operand (the bit after the or) is not executed if the first operand returns TRUE, since if one operand is TRUE in an or expression, then they both are.

Some people consider this sort of trickery to be unfavourable, since it is harder for a programmer to read yet only saves a few characters of space in the source code. Since programmer time is expensive, and disk space is cheap, you can see why people don't like this.

Instead, you should be explicit with your intent by expanding your code into a full-fledged if statement:

$handle = fopen($location, "r");
if ($handle) {
  // process the file
} else {
  return 0;
}

You can even do the variable assignment right in the if statement. Some people still find this unreadable, but most people (myself included) disagree:

if ($handle = fopen($location, "r")) {
  // process the file
} else {
  return 0;
}

One last thing: it is convention that returning 0 as a status code indicates success, so you would probably want to return a different value to indicate that you couldn't open the file.

这篇关于在PHP中,为什么“或死()”工作,但是“或返回”不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆