Isabella Wilcox
Isabella Wilcox

Reputation: 83

Object property reassignment in a loop

Why does:

$test_obj = new stdClass(); 
$array = [];
for ($i=0; $i < 5; $i++) { 
    $test_obj->num = $i;
    array_push($array, $test_obj);
}
var_dump($array);

generates:

array(5) {
  [0] =>
  class stdClass#1 (1) {
    public $num =>
    int(4)
  }
  [1] =>
  class stdClass#1 (1) {
    public $num =>
    int(4)
  }
  [2] =>
  class stdClass#1 (1) {
    public $num =>
    int(4)
  }
  [3] =>
  class stdClass#1 (1) {
    public $num =>
    int(4)
  }
  [4] =>
  class stdClass#1 (1) {
    public $num =>
    int(4)
  }
}

and:

$array = [];
for ($i=0; $i < 5; $i++) { 
    $test_obj = new stdClass(); 
    $test_obj->num = $i;
    array_push($array, $test_obj);
}
var_dump($array);

generates:

array(5) {
  [0] =>
  class stdClass#1 (1) {
    public $num =>
    int(0)
  }
  [1] =>
  class stdClass#2 (1) {
    public $num =>
    int(1)
  }
  [2] =>
  class stdClass#3 (1) {
    public $num =>
    int(2)
  }
  [3] =>
  class stdClass#4 (1) {
    public $num =>
    int(3)
  }
  [4] =>
  class stdClass#5 (1) {
    public $num =>
    int(4)
  }
}

But:

$test_obj = new stdClass(); 
$array = [];
for ($i=0; $i < 5; $i++) { 

    $test_obj->num = $i;
    array_push($array, $test_obj);
    var_dump($test_obj);
}

generates:

class stdClass#1 (1) {
  public $num =>
  int(0)
}
class stdClass#1 (1) {
  public $num =>
  int(1)
}
class stdClass#1 (1) {
  public $num =>
  int(2)
}
class stdClass#1 (1) {
  public $num =>
  int(3)
}
class stdClass#1 (1) {
  public $num =>
  int(4)
}

Can someone explain to me why var_dump within the loop is able to print out the different object property but when it gets pushed into the array, the object property becomes the last value?

Is it because I'm pushing the same object? How come during reassignment works when dealing with variable but not with object?

Upvotes: 0

Views: 31

Answers (1)

PeeHaa
PeeHaa

Reputation: 72672

You are putting the same object in your array every time:

// instance of the object
$test_obj = new stdClass(); 
$array = [];
for ($i=0; $i < 5; $i++) { 
    $test_obj->num = $i;
    array_push($array, $test_obj);
}

Is the same as doing:

$test_obj = new stdClass(); 
$array = [$test_obj, $test_obj, $test_obj, $test_obj, $test_obj];

So if you change some property of the object it will do that for all your array items, because they reference the same object:

$test_obj = new stdClass(); 
$test_obj->num = 0;
// all items in the array now are `0`
$array = [$test_obj, $test_obj, $test_obj, $test_obj, $test_obj];
$test_obj->num = 1;
// all items in the array now are `1`

The reason it works for your second example is because you are creating a new object and append it to the array.

The reason your third example does what it does is because at that point that is the value of the object:

$test_obj = new stdClass(); 
$test_obj->num = 0;
var_dump($test_obj); // ->num == 0
$test_obj->num = 1;
var_dump($test_obj); // ->num == 1
$test_obj->num = 2;
var_dump($test_obj); // ->num == 2

$test_obj = new stdClass(); 
$array = [];
for ($i=0; $i < 5; $i++) { 
    $test_obj->num = $i;
    array_push($array, $test_obj);
    // $test_obj->num == 0 on first iteration
    // $test_obj->num == 1 on first iteration
    // $test_obj->num == 3 on first iteration
    // $test_obj->num == 4 on first iteration
}

// $test_obj->num == 4 after the loop finished which is the same as your first example

Upvotes: 1

Related Questions