This code works:
$foo = getFoo();
if (!$foo) $foo = getBar();
if (!$foo) $foo = getJiggy();
if (!$foo) $foo = getWithIt();
I thought I'd seen somewhere a simplification of it with logical operators:
$foo = (getFoo() || getBar() || getJiggy() || ...);
I figured that the first true statement would get passed, but instead, it's just setting $foo to boolean true
instead of the return value of getFoo()
, getBar()
, etc.
Is there a simplification like what I'm thinking of?
For JavaScript, foo = bar || baz;
is a commonly used expression, as the ||
operator has a coalescing behavior.
PHP does not have this behavior with regard to the ||
operator, which returns a boolean value. As such, the more verbose code you originally posted:
$foo = getFoo();
if (!$foo) $foo = getBar();
if (!$foo) $foo = getJiggy();
if (!$foo) $foo = getWithIt();
is your most readable, and preferable option.
PHP 5.3 has a shorthand version of the ternary operator, which acts as a coalescing operator:
Since PHP 5.3, it is possible to leave out the middle part of the ternary operator. Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise.
This would allow you to use:
$foo = getFoo() ?: getBar() ?: getJiggy() ?: getWithIt();
However, that assumes you don't have to worry about compatibility.
You can use nested ternary operator. Something like:
$foo = (!$foo)? getFoo() : ((!$foo)? getBar() : getJiggy()) ;
Try
($foo = getFoo()) || ($foo = getBar()) || ($foo = getJiggy());
You can try
$foo = getFoo() or $foo = getBar() or $foo = getJiggy() or $foo = getWithIt();
var_dump($foo);
Output
string 'Stop Here' (length=9)
Function Used
function getFoo() {
return false;
}
function getBar() {
return false;
}
function getJiggy() {
return "Stop Here";
}
function getWithIt() {
return "Hello World";
}
You can use the weaker-precedence or
and build up a condition+assignment chain like this:
$foo = getFoo()
OR $foo = getBar()
OR $foo = getJiggy()
OR $foo = getWithIt();
For readability and easing others to understand such operator misuse, spacing is essential.
if you really want to rewrite your code, you could use call_user_func, but it's not a very elegant solution:
$foo = false;//best declare vars before using them, to avoid warnings in strict mode
$functions = array('getFoo', 'getBar','getJiggy','getWithIt');
while(!$foo && $func = array_shift($functions))
{
$foo = call_user_func($func,null);//replace null with optional parameters
}
But as you can see, this would be even less maintainable...