Does PHP Have Short-Circuit Evaluation

Does PHP have short-circuit evaluation?

Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.

If you want to verify that, try this:

function saySomething()
{
echo 'hi!';
return true;
}

if (false && saySomething())
{
echo 'statement evaluated to true';
}

Is there a short-circuit OR in PHP that returns the left-most value?

You can use just:

$a = func1() or $a = func2() or $a = func3();

or am I missing something?

PHP short-circuit evaluation

in_array looks for a value in an array. If you want to see, if a key exists, use array_key_exists instead

if (!array_key_exists('array_item', $body) || !is_int($body['array_item']))
throw new Exception();

PHP Short-Circuit Evaluation (Good/Bad?)

There's a few different questions you ask, so I'll try to address them all.

Missed branch predictions: Unless you're coding in C or assembly, don't worry about this. In PHP, you're so far from the hardware that thinking about branch predictions isn't going to help you. Either way, this would be a very-micro optimization, especially in a function that does extensive string parsing to begin with.

Is there any other reason not to use this? Wikipedia seems to think so, but only in reference to C. I know PHP is written in C, so that is definitely pertinent information.

PHP likely parses it to a different execution structure. Unless you're planning on running this function millions of times, or you know it's a bottleneck, I wouldn't worry about it. In 2012, I find it very unlikely that using an or to short circuit would cause even a billionth of a second difference.

As for the formatting, I find $a or $b rather ugly. My mind doesn't comprehend the short circuiting the same it sees it in an if clause.

if (a() || b())

Is perfectly clear to my mind that b() will execute only if a() does not evaluate to true.

However:

return a() or b();

Doesn't have the same clarity to me.

That's obviously just an opinion, but I'll offer two alternatives as to how I might write it (which are, in my opinion, a very tiny bit clearer):

function load($file) {
if (!file_exists($file)) {
touch($file);
return array();
}

$raw = file_get_contents($file);

$contents = json_decode($raw, true);

if (is_array($contents)) {
return $contents;
} else {
return array();
}

}

If you don't care if the file actually gets created, you could take it a step farther:

function load($file) {

$raw = file_get_contents($file);

if ($raw !== false) {
$contents = json_decode($raw, true);
if ($contents !== null) {
return $contents;
}
}

return array();

}

I guess really these code snippets come down to personal preference. The second snippet is likely the one I would go with. The critical paths could be a bit clearer in it, but I feel like it maintains brevity without sacrificing comprehensibility.

Edit: If you're a 1-return-per-function type person, the following might be a bit more preferable:

function load($file) {

$contents = array();

$raw = file_get_contents($file);

if ($raw !== false) {
$contents = json_decode($raw, true);
if ($contents === null) {
$contents = array();
}
}

return $contents;

}

Short-circuit evaluation via the AND operator in PHP

This is a type of "short circuit evaluation". The and/&& implies that both sides of the comparison must evaluate to TRUE.

The item on the left of the and/&& is evaluated to TRUE/FALSE and if TRUE, the item on the right is executed and evaluated. If the left item is FALSE, execution halts and the right side isn't evaluated.

$data = FALSE;
// $this->template->set_global($data) doesn't get evaluated!
$data and $this->template->set_global($data);

$data = TRUE;
// $this->template->set_global($data) gets evaluated
$data and $this->template->set_global($data);

Note these don't have to be actual boolean TRUE/FALSE, but can also be truthy/falsy values according to PHP's evaluation rules. See the PHP boolean docs for more info on evaluation rules.

PHP short circuit lazy evaluation, where is it in the php.net manual?

Closest thing I can find to an 'official' mention of PHP's short-circuit implementation: http://php.net/manual/en/language.operators.logical.php

list(), if and short-circuit evaluation

This is an issue of operator precedence, in your case, the && evaluates before the =, leading to the errors you describe.

You can resolve this problem by placing the assignment statement inside of a parentheses.

Explicitly, your code should read

if(  (list($day, $month, $year) = explode('-', $active_from))
&& !checkdate($month, $day, $year)) {

Note that I have changed it from if( $a=$b && $c ) to if( ($a=$b) && $c ). The parentheses force the assignment operator (=) to evaluate before the conjunction (&&), which is what you want.

Does PHP have short-circuit evaluation?

Yes, the PHP interpreter is "lazy", meaning it will do the minimum number of comparisons possible to evaluate conditions.

If you want to verify that, try this:

function saySomething()
{
echo 'hi!';
return true;
}

if (false && saySomething())
{
echo 'statement evaluated to true';
}


Related Topics



Leave a reply



Submit