0

I frequently use the elvis operator to set default values. Eg I have an array $x = ['value' => $value];, and then in another section of my code, $val = $x['value'] ?: '22';

In the above scenario, if $value is 3, $val should end up as 3 as well, but if $value is undefined or 0 or something, it should be 22.

When I run this sort of code on php playground, even if $x itself hasn't been defined, or if $x has no 'value' property, or if $value is not defined, it outputs 22.

However, when I run this same code on my Laravel server, the behavior is different. If $x is defined, and $x['value'] is defined as something falsy, then the evlis operator works as expected. But if $x isn't defined, or $x['value'] hasn't been set, I get an error. For example if $x is defined but $x['value'] isn't, I get an 'Undefined index' error. Here are some concrete examples, and what happens in both environments

    $x = ['value' => 0];
    $val = $x['value'] ?: '22';
    // this works on both my laravel server and the playground appropriately

    $x = [];
    $val = $x['value'] ?: '22'; 
    // on Laravel, this errors, but on the playground it sets val to 22

    unset($x);
    $val = $x['value'] ?: '22'; 
    // on Laravel, this errors, but on the playground it sets val to 22

So I'm just a bit confused about the elvis operator and how it's expected to deal with undefined values and unset indexes. Most of the time, I'd actually prefer it to behave in the way the playground is behaving -- treating undefined values as 'falsy' and defaulting to the right side of the operator. But I'm not sure what the expected behavior really is.

TKoL
  • 13,158
  • 3
  • 39
  • 73
  • 2
    Enable `error_reporting(E_ALL);` in your playground. And see the same error. – u_mulder Jan 30 '20 at 13:24
  • 2
    Or use a [playground that has a reasonable default error reporting](https://3v4l.org/UajC1). – Jeto Jan 30 '20 at 13:25
  • 1
    Worth linking: https://stackoverflow.com/q/34571330/2943403 – mickmackusa Jan 30 '20 at 13:30
  • I guess, in short, the answer is 'the Laravel application is behaving as expected' What do you guys think of something like this? `$val = ($x['value'] ?? null) ?: '22';` – TKoL Jan 30 '20 at 13:32
  • 1
    @TKoL That's right. That's what I suggested in a [recent answer](https://stackoverflow.com/a/59803492/965834), btw. – Jeto Jan 30 '20 at 13:35
  • @Jeto oh fabulous. Is that a common pattern? I just thought of it as I was struggling with this problem. – TKoL Jan 30 '20 at 13:36
  • 1
    Well, in most cases you should either be in a situation where the value is never undefined (in which case, `?:` is enough), or either undefined or valid (in which case `??` is enough). Now if both may happen, that seems like the shortest way to deal with every possibility. – Jeto Jan 30 '20 at 13:40

0 Answers0