20

Firstly is there a name for this expression ?

Javascript

var value = false || 0 || '' || !1 || 'string' || 'wont get this far';

value equals string (string) aka the fifth option

PHP

$value = false || 0 || '' || !1 || 'string' || 'wont get this far';

$value equals true (bool)

Am I right in thinking the correct way to achieve the same result as JavaScript is by nesting ternary operators? What is the best solution ?

TarranJones
  • 4,084
  • 2
  • 38
  • 55

4 Answers4

30

The equivalent operator in PHP is ?:, which is the ternary operator without the middle part:

$value = false ?: 0 ?: '' ?: !1 ?: 'string' ?: 'wont get this far';

$a ?: $b is shorthand for $a ? $a : $b.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • I think the question is not about ternary operator. But OP confusedly called ternary operator instead of short-circuit evaluation. – Bhojendra Rauniyar Apr 06 '16 at 12:22
  • 3
    In Javascript `||` returns *one of its operands*, not a boolean. The equivalent way to do that in PHP is `?:`. Question answered. – deceze Apr 06 '16 at 12:24
  • Thanks for the explanation. I was assuming something else. – Bhojendra Rauniyar Apr 06 '16 at 12:25
  • 1
    OP did not get confused, OP merely suggested using a ternary to achieve the result. – TarranJones Apr 06 '16 at 12:26
  • Just realized.. and deleted my answer to support this answer. – Bhojendra Rauniyar Apr 06 '16 at 12:26
  • You can now in PHP 7 use the null coalesce operator `??`. If used carefully, it can make you code more robust against null pointer exceptions. You can do things like: `$desperateValue = $a->b->c ?? $a->b["d"]->f ?? $foo["snafu"]->bar ?? $x ?? 'no luck';` This will return the first of these expression that will return a non null value (evaluated from left to right). The biggest advantage of this is that it evaluate nested properties and array keys and values without throwing any error. If something is not found, than the result will be null and it will move to the next expression. – asiby Jun 07 '18 at 14:26
2

If You are using PHP 5.3 or higher see deceze's answer.

Other wise you could use nested regular ternary operators.

$value = ( false ? false : ( 0 ? 0 : ( '' ? '' : ( !1 ? !1 : ( 'string' ? 'string' : ( 'wont get this far' ? 'wont get this far' : null )))))); 

Wow thats ugly.

You could use an array of values instead;

$array = array(false,0,'',!1,'string','wont get this far'));

Now create a function which iterates over the array and returns the first true value.

function array_short_circuit_eval($vars = array()){
    foreach ($vars as $var)if($var)return $var;return null;
}

$value = array_short_circuit_eval($array);

echo $value; // string
Community
  • 1
  • 1
TarranJones
  • 4,084
  • 2
  • 38
  • 55
  • 2
    `$value = current(array_filter(array(false, 0, ...)))` – I hope nobody needs to use this, but here it is... – deceze Apr 06 '16 at 13:46
1

This test false || 0 || '' || !1 || true || 'wont get this far' will return a boolean value. It will return true if any of the values is true, that's how the OR works. It's not a ternary expression, which applies the first valid value to the receiving variable.

It returns 1 to PHP because you didn't cast the expression as a boolean.

You could do this to make the expression return a boolean value instead of an integer into your PHP variable:

$value = (bool)(false || 0 || '' || !1 || true || 'wont get this far');`

The return will be true.

Phiter
  • 14,570
  • 14
  • 50
  • 84
  • 1
    *"`.. || ..` will return a boolean value..."*, *"You could do this to make the expression return a boolean value..."* – Which is it? Does `||` return a boolean or doesn't it? – deceze Apr 06 '16 at 12:25
  • It does return a boolean, but not directly into a variable, no in PHP. I don't get the two downvotes, but alrighty – Phiter Apr 06 '16 at 12:55
  • 1
    Wut? Either it returns a boolean or it doesn't. There's no difference whether you assign the return value into a variable or not. A value is a value. The boolean return value of `||` won't get any more boolean by casting it. – deceze Apr 06 '16 at 13:05
0

Another approche with 'or' and '=' operators.

example:

in Javascript:

$value = false || 0 || !1 || 'woow, i am selected';

in Php:

$value = false or $value = 0 or $value = !1 or $value = 'woow, i am selected';

This is possible because in Php 'or' operator has lower precedence order then '=' (assignment).

Naro
  • 800
  • 6
  • 11
  • @NicoHaase Its not a duplicated answer, this answer is using the combination of operators (or, =) and provides a correct result. – Naro Jun 26 '23 at 23:53