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
PHP - How to Create a Newline Character
Get Value from Simplexmlelement Object
Upgrading My Encryption Library from Mcrypt to Openssl
Remove All HTML Tags from PHP String
Pulling Track Info from an Audio Stream Using PHP
How to Parse a CSV File Using PHP
Glob() - Sort Array of Files by Last Modified Datetime Stamp
List All the Files and Folders in a Directory With PHP Recursive Function
Make Xampp/Apache Serve File Outside of Htdocs Folder
Secure Random Number Generation in PHP
How to Remove Accents and Turn Letters into "Plain" Ascii Characters
Nginx Location Configuration (Subfolders)
How to Truncate a String to the First 20 Words in PHP
How to Fix the Session_Register() Deprecated Issue