Is this PHP syntax correct?
I am currently studying ZEND framework and came across this in index.php:
// Define path to application directory
defined('APPLICATION_PATH'开发者_运维技巧)
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
Is this the same as this?
if(!defined('APPLICATION_PATH')){
define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
}
I have never came across this type of shorthand syntax before.
||
is a short-circuit operator which means that the second operand, in this case define(...)
is only evaluated in case the first operand evaluates to false. Because operands to shirt-circuit operators may actually have side effects as is your case, short-circuiting may substitute an if
statement.
Check this article: http://en.wikipedia.org/wiki/Short-circuit_evaluation
Functionally, yes, it is the same. The defined
function returns a boolean, so it uses short-circuit evaluation to mean "either this is defined, OR execute this definition."
Yes. However, it's based on the way PHP implements boolean evaluation and should not be considered an idiomatic construct. It will almost assuredly work in future releases of PHP but I would still discourage this syntax as it lacks expressiveness.
Here's a short explanation on why this syntax works:
Boolean expressions in PHP have the form:
left_expression BOOLEAN_OPERATOR right_expression;
where BOOLEAN_OPERATOR
is a logical operator, ||
for example.
Since OR expressions evaluate to true as soon as one of their operands evaluates to true
, the PHP interpretor can stop evaluating as soon as it finds an operand that evaluates to true
.
In this case if defined('APPLICATION_PATH')
evaluates to true, define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'))
won't be evaluated. If defined('APPLICATION_PATH')
evaluates to false, PHP needs to evaluate define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'))
.
So whenever,
- the left expression evaluates to false, the right is evaluated.
- the left expression evaluates to true, the right is not evaluated.
It is called short circuiting. OR (||
) will only evaluate the second part if the first part is false. Similarly, AND (&&
) can be used to only evaluate the second part if the first part is true.
Yes. PHP is lazy and if there is a logical or statement, it will stop after the first evaluates true.
You got the idea right. Most imperative statements in PHP return booleans that can be used for short-circuiting. Even those that return void (equivalent to null/false) can be used in the same manner.
Yes. Remember that the "or" operator ||
is evaluted "Lazily" - if the first part evaluates to "TRUE" the second part is not run, because it's result would have no effect on the statement overall. Same thing goes for && - if the first part is FALSE the second won't be run.
精彩评论