1

I'm facing some strange behavior with the array_shift function in PHP:

function shift($arr)
{
  array_shift($arr);
}

$a = [1, 2, 3];
shift($a);
print_r($a);

Output:

Array ( [0] => 1 [1] => 2 [2] => 3 ) 

My Expected Output:

Array ( [0] => 2 [1] => 3 ) 

Explanation:

I believe that $a and $arr, despite being different references, point to the same array object. I expect array_shift to look where $arr is pointing and modify (shorten) that array. Then that change will be visible when looking up the array via $a.

However, when I test my theory, no change is visible. The array is just as long as before array_shift was called. What gives?

2
  • Why not use unset and array_slice? Commented Jul 11, 2017 at 21:36
  • Don't panic's answer explains your problem. I do want to point out that all objects are passed by reference since PHP 5, so this does lead to confusion, because there are many times when you don't need to utilize the '&' when you are defining a parameter, and with the proliferation of PHP OOP, people are frequently using objects, but for all other variable types, you need the '&' to designate "Pass a reference" to this variable. Commented Jul 11, 2017 at 21:50

1 Answer 1

3

The $arr inside your function is not the same array as $a. A local copy is created unless you pass it by reference, e.g.

function shift(&$arr) ...

Check the PHP documentation on variable scope:

However, within user-defined functions a local function scope is introduced. Any variable used inside a function is by default limited to the local function scope.


array_shift is working the way you expect it to, though. You can add a print_r($arr); inside your function after you do the array_shift to see the shortened version of the array within the function scope. It just won't affect the original array unless you pass it by reference.

Sign up to request clarification or add additional context in comments.

5 Comments

Wow! This is surprising to me coming from Java. They call Java pass-by-value too, but it exhibits the opposite behavior. Is it like this with all objects in PHP? For example, if I pass an instance of one of my own classes to a function, and then call one of its methods to alter it, does the object remain unchanged outside of the function?
Well, no, actually. When you pass an instance of a class, you're actually passing the object identifier rather than the actual object. Kind of like passing a reference but not exactly the same thing. An array isn't really considered to be an object, though. I should probably change that phrasing in my answer.
Oh, so is it safe to say that passing non-array objects in PHP works like passing objects in Java?
To be honest, I'm not sure exactly how it works in Java, but as far as it being the same object in the function scope, actual objects will be, but none of the primitive types (including arrays) will, unless passed by reference.
Thanks for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.