PHP的array_push()会覆盖现有数组元素

3
我正在尝试将对象推入数组中,以得到像这样的对象数组:
[
    {"recipient_name":"John D", "phone_number":"123456"},
    {"recipient_name":"Doe J", "phone_number":"654321"},
    {"recipient_name":"Jon Do", "phone_number":"112233"},
]

所以我正在循环遍历一个较大的数组来获取姓名和电话号码,并将它们作为对象推送到一个数组中,如下所示:

$myLargerArray = pg_fetch_all($messageQuery); // This is my larger array

$size = count($myLargerArray);
for( $j = 0; $j < $size; $j++ ) {
    $myRecipientsObj->recipient_name = $myLargerArray[$j]['recipient_name'];
    $myRecipientsObj->phone_number = $myLargerArray[$j]['phone_number'];

    var_dump($myRecipientsObj); // This outputs the correct data added from [$j]

    array_push($myObjArray->message_recipients, $myRecipientsObj);

    var_dump($myObjArray->message_recipients); // The output shows array elements are being overwritten at each loop iteration
}

这是一个关于 var_dump($myObjArray->message_recipients) 最终输出结果的示例:
array(1) {
  [0]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(12) "First Person"
    ["phone_number"]=>
    string(9) "112233445"
  }
}
array(2) {
  [0]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(13) "Second Person"
    ["phone_number"]=>
    string(9) "123456789"
  }
  [1]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(12) "Second Person"
    ["phone_number"]=>
    string(9) "123456789"
  }
}
array(3) {
  [0]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(16) "Third Person"
    ["phone_number"]=>
    string(9) "012345678"
  }
  [1]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(16) "Third Person"
    ["phone_number"]=>
    string(9) "012345678"
  }
  [2]=>
  object(stdClass)#2 (2) {
    ["recipient_name"]=>
    string(16) "Third Person"
    ["phone_number"]=>
    string(9) "012345678"
  }
}
array(4) {
  ... // it just overwriting the data with duplicates
}

我做错了什么导致出现这种情况,我该如何解决?

3个回答

10

这是因为当你使用:

array_push($myObjArray->message_recipients, $myRecipientsObj);

您正在将对该对象的引用推入数组中,并且当您在后续循环中更改对象时,实际上会更改数组每个元素的内容。为解决此问题,您需要推入该对象的副本而不是引用到数组中:

array_push($myObjArray->message_recipients, clone $myRecipientsObj);

3v4l.org上的演示


1
哇,这个方法可行。我从来没有想过使用克隆,因为我认为将元素推入数组中的方法就像 JS 中的对应方法一样。 - Clint_A

1
您可以直接在message_recipients前面写上[],如下所示:
$myObjArray->message_recipients = [];
for ($j = 0; $j < $size; $j++) {
    $myRecipientsObj                 = new stdClass; // created std class object
    $myRecipientsObj->recipient_name = $myLargerArray[$j]['recipient_name'];
    $myRecipientsObj->phone_number   = $myLargerArray[$j]['phone_number'];
    $myObjArray->message_recipients[] = $myRecipientsObj;
}

它应该可以工作。

正在工作 demo


让我试试。虽然值得一提的是,我已经将它初始化为一个数组 $myObjArray->message_recipients = Array(); - Clint_A

0
$myObjArray->message_recipients[] = \DeepCopy\deep_copy($myRecipientsObj);

请问您可以添加一些描述吗? - executable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接