5

First code and then the question:

class MyArray
{
    private $arrayRef;

    function __construct(&$array){
        $this->arrayRef = $array;
    }

    function addElement($newElement){
        $this->arrayRef[] = $newElement;
    }

    function print(){
        print_r($this->arrayRef);
    }
}

$array = ['first', 'second'];
$arrayObject = new MyArray($array);
$arrayObject->addElement('third');

print_r($array); // prints array containing 2 elements
echo '<br/>';
$arrayObject->print(); // prints array containing 3 elements

Class member $arrayRef, in this example doesn't work as a reference to another array provided in constructor. Argument in constructor is passed by reference, but I guess that doesn't make member $arrayRef also a reference to that array as well.

Why doesn't it work like that and how to make it work?

If you still don't get what I mean: first print_r prints array containing 2 elements, even thought it may be expected to contain 3. When I pass third element to $arrayObject via addElement() I also want it to be added in the $array that I passed to constructor of class.

2
  • Yes, your constructor takes a value by reference, but it makes a local copy of it on the line: $this->arrayRef = $array;. The rest of the class is working on the instantiated object's copy (this->arrayRef), not the original $array. Do you want a global variable instead? Commented Nov 8, 2016 at 22:39
  • I want member $arrayRef to be a reference to an array passed in constructor so that any changes made $arrayRef are also made to passed array Commented Nov 8, 2016 at 22:44

1 Answer 1

6

The answer is actually quite simple. Yes, you pass the array by reference via &$array but this reference gets lost when you assign/copy it to the member variable. To keep the reference, you can use the =& operator like so

$this->arrayRef =& $array;

See it work in this fiddle. You can read more about it in this question/answer (just look for reference).

Beware not to use &= (which does a bitwise operation) instead of =& (which assigns by reference).

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

6 Comments

Okay, I have modified that line the way you suggested, but now I have a problem assigning new values to array, I get error: Cannot use a scalar value as an array. End in debug mode I see taht value of $arrayRef is 0. WTF? $array passed in constructor is initialized. This is now an another question but I would still prefer you'd answer :). If not, still fine. Will check on that error tomorrow.
Oh sorry, I've failed to rewrite your line of code. I've written $this->arrayRef &= $array; LOL
Yeah this is tricky. As you can see in the last link I posted in the answer, &= does a bitwise operation while =& assigns by reference. To be honest, working with references like this is quite uncommon in PHP, so I had to look it up myself (you usually just return the new array and go on from there). I've added this pitfall. If this answered your question, please consider marking it as accepted
I need this for a specific purpose. Could you still just explain why is copying the whole array more standard/better than just providing a reference to it? If deep copy isn't necessary? I really don't get it. Isn't it slower?
I think standard is the word here rather than better. Of course, this is just my personal opinion, but as I said working with copies rather than references is more common in PHP. Other than that, sadly, I have no answer. You are welcome to dig through large/commonly used frameworks. Or look at the internal functions themselves. You rarely see references (and when you do, it is with very old functions), but rather returning a modified copy. All of the array functions (array_unique, _merge, etc) do it like this i.e.
|

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.