Since PHP 7.3 `array_unshift()` can be called with only one parameter. What's the point?
Asked Answered
L

2

6

As it said in the PHP manual about array_unshift() function:

7.3.0 This function can now be called with only one parameter. Formerly, at least two parameters have been required.

I didn't get it. How to use such function with only one parameter?

I tried to guess, but nothing happens:

$arr = ['one' => 'test', 'two' => 'some'];
array_unshift($arr);
print_r($arr);

// Result:
// Array
// (
//    [one] => test
//    [two] => some
// )

$arr1 = ['what', 'ever'];
array_unshift($arr1);
print_r($arr1);

// Array
// (
//    [0] => what
//    [1] => ever
// )

The arrays haven't changed.

Does anyone know what exactly PHP contributors suggest?

Loveinidleness answered 10/7, 2020 at 11:7 Comment(5)
As Php Manual say, Returns the new number of elements in the array., so you can use that function for return number of element. in this case same at the original.Correlative
According to raw.githubusercontent.com/php/php-src/PHP-7.3/UPGRADING - array_push() and array_unshift() can now also be called with a single argument, which is particularly convenient wrt. the spread operator.Merrymaker
The point is that you can use an unpacked array for the second and subsequent arguments, and won't get back a warning if the array is empty. The change was made in this pull request, which has some (brief) discussion about it.Supplicatory
@SimoneRossaini php::count() do that job in the explicit way. I'm pretty sure that authors didn't want to provide to us another strange method for counting the array :)Loveinidleness
@iainn, thanks for the link. Now I know, what they tried to do. But I can't invent any useful example how to unpack array and unshift or making something else that will work in a predictable correct way. I'm still thinking that this is useless improvement.Loveinidleness
S
2

I think my comment might need some more explanation, hopefully this makes it clearer.

If I have two arrays, and I want to add all elements from the second to the end of the first, using array_push combined with the unpacking operator lets me do it like this:

$a = [1, 2, 3];
$b = [4, 5, 6];

array_push($a, ...$b);

$a is now [1, 2, 3, 4, 5, 6]

(array_unshift lets me do the same, but add the elements to the beginning of the array instead. Using array_push I think makes the example clearer)

Before PHP 7.3, if $b was empty then a warning would be raised, as unpacking an empty array is the equivalent of only passing the first argument. See the demo here: https://3v4l.org/GZQoo. $a would still be unchanged, which is the desired outcome, so it's just unnecessary noise in the logs.

In a practical example, if $b was being generated by another function (calling a database, etc) then without this change I'd need to call if (!empty($b) ... before running the code to prevent the warning. Now, it works silently.

Note: There are other ways of appending an array to another (array_merge, array_replace and the + operator), but they all have particular ways of merging and de-duplicating shared keys. This method simply appends all values of the second to the first, regardless of the keys.

Supplicatory answered 11/7, 2020 at 17:46 Comment(1)
Technically we still call the function with two parameters. But using a splat operator our call may implicitly turned to one-parameter case.Loveinidleness
L
2

That's just a guess, but as the function returns:

Returns the new number of elements in the array.

you can use it as count alternative:

$arr1 = ['what', 'ever'];
print_r(array_unshift($arr1));    // 2

But of course it's not obvious.

As another side effect from manual:

All numerical array keys will be modified to start counting from zero

So, it's a partial replacement for array_values:

$arr1 = [4 => 'what', 5 => 'ever'];
array_unshift($arr1);
print_r($arr1);  // [[0] => what [1] => ever]

And it's not obvious too.

Also maybe other answers will explain this behaviour better.

Also, thanks to @NigelRen, in the official manual you can read that

array_push() and array_unshift() can now also be called with a single argument, which is particularly convenient wrt. the spread operator.

So, you can use something like:

$arr1 = [['what'], ['ever']];
array_unshift(...$arr1);
print_r($arr1);

But behaviour of this method is very strange o_O:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => ever
                )

            [1] => what
        )

    [1] => Array
        (
            [0] => ever
        )

)
Lenhart answered 10/7, 2020 at 11:11 Comment(2)
I didn't find the @NigelRen comment. But nevertheless the result is wierd indeed :) [UPD] Oh! I found the comment. I thought it was placed in the PHP manual :)Loveinidleness
I also thought that such calling relates to array count, but you're damned right - it is not obvious, at the same time when count() exists. So I think this not the point that authors targeted.Loveinidleness
S
2

I think my comment might need some more explanation, hopefully this makes it clearer.

If I have two arrays, and I want to add all elements from the second to the end of the first, using array_push combined with the unpacking operator lets me do it like this:

$a = [1, 2, 3];
$b = [4, 5, 6];

array_push($a, ...$b);

$a is now [1, 2, 3, 4, 5, 6]

(array_unshift lets me do the same, but add the elements to the beginning of the array instead. Using array_push I think makes the example clearer)

Before PHP 7.3, if $b was empty then a warning would be raised, as unpacking an empty array is the equivalent of only passing the first argument. See the demo here: https://3v4l.org/GZQoo. $a would still be unchanged, which is the desired outcome, so it's just unnecessary noise in the logs.

In a practical example, if $b was being generated by another function (calling a database, etc) then without this change I'd need to call if (!empty($b) ... before running the code to prevent the warning. Now, it works silently.

Note: There are other ways of appending an array to another (array_merge, array_replace and the + operator), but they all have particular ways of merging and de-duplicating shared keys. This method simply appends all values of the second to the first, regardless of the keys.

Supplicatory answered 11/7, 2020 at 17:46 Comment(1)
Technically we still call the function with two parameters. But using a splat operator our call may implicitly turned to one-parameter case.Loveinidleness

© 2022 - 2024 — McMap. All rights reserved.