6

In Javascript, we can conveniently get one of the various options that is offered in || operator. For example:

console.log('a' || '' || 0); // Yields 'a'
console.log(0 || 'b' || 'a'); // Yields 'b'

Those results above can easily be assigned to a variable like this:

let test = 'a' || '' || 0;

In PHP, though, when I try this:

$test = 'a' || '' || 0; gives me a $test = 1, with 1 meaning true. Is there a way in PHP to get the literal value of the expression which caused it to yield true?

Richard
  • 7,037
  • 2
  • 23
  • 76
  • 1
    See the user-contributed notes of [PHP's logical operators page](http://php.net/manual/en/language.operators.logical.php). – FThompson Feb 25 '19 at 06:48
  • @Vulcan It seems like the user-contributed notes are only dealing with two values to compare. When it becomes three or more, won't I have to use nested ternary operators (which I recall reading somewhere is bad practice)? – Richard Feb 25 '19 at 06:51
  • `||` doesn’t return `1`, it always returns a Boolean; which may be *printed* as `1` in the case of `true`… – deceze Feb 25 '19 at 07:08

3 Answers3

2

You can use the Elvis operator for this purpose, e.g.

$test = 'a' ?: '' ?: 0;
var_dump($test);
> string(1) "a"

$test2 = 0 ?: 'b' ?: 'a';
var_dump($test2);
> string(1) "b"

There is also null coalescing operator (??) but it takes the second value only if the first is null, so e.g. 0 ?? 'a' will take 0 because it's not null.

Karol Samborski
  • 2,757
  • 1
  • 11
  • 18
  • THIS is seriously good. The null-coalescing operator `??` is really good too, though. I take your answer, thank you :-) – Richard Feb 25 '19 at 07:00
  • A link to the manual http://php.net/manual/en/language.operators.comparison.php "Expression expr1 ?: expr3 returns expr1 if expr1 evaluates to TRUE, and expr3 otherwise." – Nick Feb 25 '19 at 07:00
  • 1
    @RichardW the null coalesing operator won't work for `$test2 = 0 ?? 'b' ?? 'a';` as 0 is not null, the expression will return 0, not 'b' – Nick Feb 25 '19 at 07:02
  • @Nick I see, thank you for pointing that out. The Elvis operator is better in my case, then. I think that the answerer should add that to the answer so other visitors may get better insights in regard to this topic. – Richard Feb 25 '19 at 07:04
  • @RichardW I've updated my answer about null coalescing operator as well. – Karol Samborski Feb 25 '19 at 07:19
1

Per some user-contributed comments on PHP's logical operators page, you can use the ternary operator:

$test = $a ? $a : ($b ? $b : 'default')

Or if you're running PHP 7+ and you only need to pass over null variables (rather than falsy variables) you can use the null-coalescing operator ??:

$test = $a ?? $b ?? 'default'
FThompson
  • 28,352
  • 13
  • 60
  • 93
  • I read somewhere (I really can't recall where) that using nested ternary operators is bad, though. It looks rather bulky for a one line code, but thank you for the null-coalescing operator, it's very clean. – Richard Feb 25 '19 at 06:58
  • Since PHP 5.3, you could also use the "elvis operator": `$test = $a ?: $b ?: 'default';` – M. Eriksson Feb 25 '19 at 06:59
  • 1
    I'd shy away from the nested ternary operators - but elvis `?:` or null-coalescing `??` operators are quite good. – Qirel Feb 25 '19 at 07:00
  • @MagnusEriksson I didn't know about the elvis operator but I would say that's the cleanest way of doing this. – FThompson Feb 25 '19 at 07:00
  • @MagnusEriksson I believe I note that it doesn't check falsiness in my answer but maybe I could be more clear? – FThompson Feb 25 '19 at 07:03
  • 1
    Correct, nested ternary operators (more probably referred to as the conditional operator) is bad, especially within PHP as it behaves differently from other languages. For example `echo true?'yay':true?'doh':'doh';` echos `doh` rather than what many would expect to be `yay`. But if you use it with parenthesis, be my guest as then it's clear the author knew the order it was executing. `echo true?'yay':(true?'doh':'doh');` will yield the expected `yay` as it does in other languages such as JavaScript. – Ultimater Feb 25 '19 at 07:04
  • @Vulcan - Nah. It's rather me that needs to be more observant of what you've written. :-) – M. Eriksson Feb 25 '19 at 07:04
0

PHP's boolean operators always return a boolean value... as opposed to other languages that return the value of the last evaluated expression.

For example:

$a = 0 || 'avacado';
print "A: $a\n";

will print:

A: 1

in PHP -- as opposed to printing "A: avacado" as it would in a language like Perl or JavaScript.

This means you can't use the '||' operator to set a default value:

$a = $fruit || 'apple';

instead, you have to use the '?:' ternary operator:

$a = ($fruit ? $fruit : 'apple');

if you're using PHP 7+ then you can user null-coalescing operator ??: too.

<?php
// Fetches the value of $_GET['user'] and returns 'nobody'
// if it does not exist.
$username = $_GET['user'] ?? 'nobody';
// This is equivalent to:
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

// Coalescing can be chained: this will return the first
// defined value out of $_GET['user'], $_POST['user'], and
// 'nobody'.
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
?>

For more information, you can refer to this link. For null coalescing operator use this

link

.

Jigar
  • 3,055
  • 1
  • 32
  • 51