0

I've read up about PHP variable references but I'm not 100% and was hoping someone could help.

If I have a class like the following:

class Item
{
    public $value;
}

I then have an array of those items in a variable - lets call that $items. All I did was new Item()...and $items[] = $newItem;.

Now, I want to populate another array but it filters the original array based on its value. So like the following:

foreach($items as $key => $value)
{
    $filteredItems[] = &value;
}

Now, I have ANOTHER variable that iterates over that filtered list and does something like so:

$theItem = $filteredItems[10];
$theItem->value = 100;

Now this is where I'm confused. Do I need to set $theItem to &filteredItems[10]; (reference) or will it just know that the value in the array is a reference type and $theItem also becomes a reference to that same item? I'm after that last set of $theItem->value = 100; changes the very original object stored in the $items list.

4
  • 3
    Object instances are always kept and assigned as references, regardless of &. If you want to keep the filtered list distinct from the original object list, you'd have to clone each entry. Commented Aug 11, 2013 at 21:03
  • @mario One of the key-points of PHP 5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true. This section rectifies that general thought using some examples. from php.net/manual/en/language.oop5.references.php Commented Aug 11, 2013 at 21:05
  • @ndm The manual does a pretty poor job of explaining the difference, but it's more than a mere technicality: $foo = new Foo(1); $bar = $foo; $baz =& $foo; $foo = new Foo(2); results in $foo and $baz pointing to the same object (since they were linked as references) but $bar pointing to the original object (whose object-pointer was copied in the assignment by value) Commented Aug 11, 2013 at 21:33
  • @IMSoP You're right... I should have said that even tough they are not passed by reference, they will nonetheless point to the same object so that there's no need to explicitly pass by reference. Commented Aug 11, 2013 at 21:55

2 Answers 2

4

In PHP 5 objects are always passed around by their "handle" for lack of better word. This means if you do this:

$a = new Item();
$a->value = 1;

$b = $a;
$b->value++;

echo $a->value;

The value of 2 is echoed. Why? Because the handle of the object is copied from $a to $b and they both point to the same object. This isn't a reference in terms of using &, but behaves similarly enough to the point that people generally call it the same thing... even though it's not.

So you do not need any use of references in your code. Usually in PHP, you never need to use references when using objects.

With respect to objects, you really only notice references if you do this (assign a new value to the variable itself):

function foo(Item &$a)
{
  $a = null;
}

$b = new Item();
foo($b);
var_dump($b);

This results in NULL, which wouldn't happen without a reference. But again, this is not typical usage, so you can really forget about using references with objects.

(And of course the use of a function isn't necessary here to illustrate the point, but that's the most typical place you'll see them in the "real world.")

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

1 Comment

After further extensive testing of adding reference '&' symbols everywhere and taking them all out, the behaviour was the same. Thank you for the detailed explanation.
0

It's like this:

foreach($items as $key => &$value) {
    $filteredItems[] = $value;
}

The point where you give the original instance into a different scope is where you put the &. Same is for functions:

function myFunction(&$variable) { }

Example:

<?php
class test {
    public $testVar;
    public function __construct() {
        $this->testVar = "1";
    }
}

function changeByReference(&$obj) {
    $obj->testVar = "2";
}

$instance = new test();
// Prints 1
echo $instance->testVar, PHP_EOL;  
changeByReference($instance);
// Prints 2
echo $instance->testVar, PHP_EOL;

Read more about it here: http://php.net/manual/en/language.oop5.references.php

If you want to copy an instance, use clone - php.net/clone

The easiest way to get it is when you know the difference between these: class, object and instance. (I'd explain it more at this point but it would only confuse you more because my english is not accurate enough for now to explain the details enough.)

1 Comment

This is incorrect: the changeByReference function always takes an object, which will be passed as an object handle, so does not need to be passed by reference.

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.