4

I was reading about and experimenting a bit with ternary and null coalescing operators in PHP.

So, instead of writing

if (isset($array['array_key']))
{
    $another_array[0]['another_array_key'] = $array['array_key'];
}
else
{
    // Do some code here...
}

and instead of shortening it with null coalescing or ternary operator I tried to further shorten the code with the null coalescing but without the 'else' part as I didn't really needed. I searched for it and found some solutions that weren't what I wanted.

I tried this and both solutions worked!

$another_array[0]['another_array_key'] = $array['array_key'] ??
$another_array[0]['another_array_key'] = $array['array_key'] ? :

print_r($another_array);

Note there is no ; at the end of the line above.

My question is: Would this be an acceptable piece of code? I think it might be hard to explain it with a comment, as it can be a burden in readability after some time.

Sorry if it's a similar question - I didn't really had time to check them all as there was quite a few suggested by Stack Overflow.

This would be the kinda 'complete' code example:

<?php

$another_array = [];

$array = [
    'name' => 'Ivan The Terrible',
    'mobile' => '1234567890',
    'email' => 'tester@test.com'
];

if (isset($array['name']))
{
    $another_array[0]['full_name'] = $array['name'];
}


$another_array[0]['occupation'] = $array['occupation'] ??
// or $another_array[0]['occupation'] = $array['occupation'] ? :

print_r($another_array);
  • You've answered your own question. Write source code for someone else to read and not yourself if you want it to be maintainable. – Reactgular Jan 17 '20 at 13:05
  • 2
    Regarding *"Note there is no ; at the end of the line above."*: This probably makes it invalid in almost all circumstances and yield unexpected results in all others. Meaning you'll need to put something there, making it then a lot more readable. – Yoshi Jan 17 '20 at 13:08
  • Also note, that `?:` is not equivalent to `??`. The first will will result in an `PHP Notice` if the key does not exist on the array. – Yoshi Jan 17 '20 at 13:11
  • Thanks @Yoshi - I've fixed the last part of the code. – IvanTheTerrible Jan 17 '20 at 13:13
  • The purpose of ternary expression are to avoid code like `if ($condition) { $foo = 42; } else { $foo = $bar; }`. Now, if your else part doesn't set anything in `$another_array[0]['another_array_key']` and/or do something else, then ternaries aren't a solution. – Cid Jan 17 '20 at 13:17
  • 5
    _“and both solutions worked”_ - you are wrong here by considering this _two_ things to begin with. This works without a semicolon, because the whole thing is considered _one_ expression. (The line breaks have no syntactical meaning here, they do not separate this into multiple individual expressions as might be the case in some other language.) – 04FS Jan 17 '20 at 13:17
  • 2
    Thanks @Cid. I've added the example there. – IvanTheTerrible Jan 17 '20 at 13:20
  • Just to mention that I've tested the code on http://sandbox.onlinephpfunctions.com/ with all major PHP 7 versions and it works well. – IvanTheTerrible Jan 17 '20 at 13:22
  • Thanks for your help @Cid. I think @04FS pointed out the flaw I had in the code. I've added another line of code after the `print_r($another_array);` and it appears it still included the 'occupation' key in the last print out just because the `print_r($another_array)` was interpreted as 1. Thank you all! – IvanTheTerrible Jan 17 '20 at 13:34

1 Answers1

2

Reabability, maintainability... If you want to test many possible array keys and then add them or not in a final array, nothing stops you from creating a 3rd array that will hold the keys to check and loop through it :

<?php

$another_array = [];

$array = [
    'name' => 'Ivan The Terrible',
    'mobile' => '1234567890',
    'email' => 'tester@test.com'
];

$keysToCheck = [
    // key_in_the_source_array => key_in_the_target
    'name' => 'full_name',
    'occupation' => 'occupation'
    // if you want to test more keys, just add them there
];

foreach ($keysToCheck as $source => $target)
{
    if (isset($array[$source]))
    {
         $another_array[0][$target] = $array[$source];
    }
}

print_r($another_array);

Please take note that

$another_array[0]['occupation'] = $array['occupation'] ??

print_r($another_array);

is evaluated as

$another_array[0]['occupation'] = $array['occupation'] ?? print_r($another_array);

If you add another print_r($another_array); after, you'll notice that $another_array[0]['occupation'] => true because of the return value of print_r()

Cid
  • 14,968
  • 4
  • 30
  • 45
  • 1
    Precisely @Cid. I've just added a comment here: https://stackoverflow.com/questions/59787912/omitting-the-else-in-php-ternary-and-null-coalescing-operators#comment105719352_59787912 – IvanTheTerrible Jan 17 '20 at 13:36
  • @IvanTheTerrible yep, I just saw it – Cid Jan 17 '20 at 13:37