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?

Vijit
  • 328
  • 3
  • 12
  • 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. – Simone Rossaini Jul 10 '20 at 11:15
  • 1
    According to https://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.* – Nigel Ren Jul 10 '20 at 11:16
  • 1
    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](https://github.com/php/php-src/pull/3011), which has some (brief) discussion about it. – iainn Jul 10 '20 at 11:33
  • @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 :) – Vijit Jul 11 '20 at 16:46
  • @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. – Vijit Jul 11 '20 at 17:02

2 Answers2

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
        )

)
u_mulder
  • 54,101
  • 5
  • 48
  • 64
  • 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 :) – Vijit Jul 11 '20 at 16:40
  • 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. – Vijit Jul 11 '20 at 16:42
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.

iainn
  • 16,826
  • 9
  • 33
  • 40
  • Technically we still call the function with two parameters. But using a splat operator our call may implicitly turned to one-parameter case. – Vijit Jul 12 '20 at 13:44