循环中的对象属性重新分配


Object property reassignment in a loop

为什么:

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

生成:

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)
  }
}

和:

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

生成:

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)
  }
}

但是:

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

生成:

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)
}

有人能向我解释一下为什么循环中的var_dump能够打印出不同的对象属性,但当它被推入数组时,对象属性会变成最后一个值吗?

是因为我在推同一个物体吗?当处理变量而不处理对象时,为什么在重新分配期间有效?

每次都在数组中放入相同的对象:

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

与做相同:

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

因此,如果您更改对象的某些属性,它将对所有数组项执行此操作,因为它们引用相同的对象:

$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`

它适用于第二个示例的原因是,您正在创建一个新对象并将其附加到数组中。

你的第三个例子之所以这么做,是因为在这一点上,这就是对象的价值:

$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