0

Here's my code:

$words = array();
$word = "this";
$words[] = $word;
$word = "that";
$words[] = $word;
print_r($words);

class word{
    private $text;
    public function __construct($word){
        $this->text=$word;
    }

    public function setWord($word){
        $this->text=$word;
    }
}

$class_words = array();
$word = new word("this");
$class_words[] = $word;
$word->setWord("that");
$class_words[] = $word;
print_r($class_words);
exit; 

Here's the output:

Array
(
    [0] => this
    [1] => that
)
Array
(
    [0] => word Object
        (
            [text:word:private] => that
        )

    [1] => word Object
        (
            [text:word:private] => that
        )

)

I expected the second output to match the first in that the array should store 'this' and 'that'. It seems array_name[] = <item> makes a copy to the item when it's an array of values but not so when it's an array of objects. How do I make it copy the object to the array instead copying a reference to the object? Do I need to create a new object each time I need to add an object to the array?

Meyer Auslander
  • 349
  • 1
  • 10

4 Answers4

1

If you want to copy the value of the object into the array you need to write a "getter" for the value e.g.

class word{
    private $text;
    public function __construct($word){
        $this->text=$word;
    }

    public function setWord($word){
        $this->text=$word;
    }

    public function getWord() {
        return $this->text;
    }
}

$class_words = array();
$word = new word("this");
$class_words[] = $word->getWord();
$word->setWord("that");
$class_words[] = $word->getWord();
print_r($class_words);

Output:

Array
(
    [0] => this
    [1] => that
)

Demo on 3v4l.org

Nick
  • 138,499
  • 22
  • 57
  • 95
1

$x = new X(); stores a reference to an object into $x. A subsequent $y = $x; copies the reference, not the object, so $x and $y both refer to the same object.

PHP has rather complex semantics regarding references.

wowest
  • 1,974
  • 14
  • 21
0

Objects are always references; all your uses of $word refer to the same object and the same data structure. You need to do:

$class_words=[new word('this'),new word('that')];
Dinu
  • 1,374
  • 8
  • 21
0

Both elements of your array hold the same object. So whenever you make a change in that object, all references to that object will show that change-- they're all referring to the same object in its current state.

As mentioned previously, if you want different values, you need to either instantiate new objects, or get the property value via a getter() that returns a simple value (string, integer, boolean, etc), not the object itself.

As a side note, you can leverage the referential nature of objects to chain methods ($Obj->method1()->method2()->method3()) by having a method return a reference to the object, i.e., return $this;

Tim Morton
  • 2,614
  • 1
  • 15
  • 23