正在修改重复数组中的PHP对象

正在修改重复数组中的PHP对象,php,arrays,Php,Arrays,我有一个多维数组,其中一些元素是对象。我希望最终得到两个数组,一个是通过esc函数传递了所有字符串值和对象属性的数组,另一个是未修改的原始数组 给定以下代码: $raw = $data; echo $raw['obj']->description; // Prints '< >Test Desc' array_walk_recursive($data, function (&$item, $key){ if(is_string($item)) { $

我有一个多维数组,其中一些元素是对象。我希望最终得到两个数组,一个是通过esc函数传递了所有字符串值和对象属性的数组,另一个是未修改的原始数组

给定以下代码:

$raw = $data;
echo $raw['obj']->description; // Prints '< >Test Desc'

array_walk_recursive($data, function (&$item, $key){
   if(is_string($item)) {
      $item = esc($item);
   } elseif(is_object($item)) {
      foreach ($item as $property => $value)  {
          if(is_string($value)) {
              $item->$property = esc($value);
          }
      }
   }
});

echo $data['obj']->description; // Prints '&lt; &gt;Test Desc' - Correct
echo $raw['obj']->description; // Prints '&lt; &gt;Test Desc' - Incorrect

我希望$raw是完全未修改的,而$data是通过esc处理的。除对象属性外,情况也是如此。出于某种原因,$raw中的对象也会被修改,以便两条回显线打印不同的值,这是为什么?

因为PHP5对象总是通过引用传递

您必须克隆对象才能真正复制它们


有关详细信息,请参阅。

,因为PHP5对象总是通过引用传递

您必须克隆对象才能真正复制它们


有关详细信息,请参阅。

对象在PHP中通过引用传递。这意味着,如果将对象$a分配给变量$b,则$a和$b都将指向同一个对象。手册页对此进行了更详细的解释

您可以使用操作符来真正克隆对象:

$b = clone $a;

不过,这只适用于对象,因此必须递归地复制数组,在其中使用对象克隆。

对象在PHP中通过引用传递。这意味着,如果将对象$a分配给变量$b,则$a和$b都将指向同一个对象。手册页对此进行了更详细的解释

您可以使用操作符来真正克隆对象:

$b = clone $a;

不过,这只适用于对象,因此您必须递归地复制数组,在其中使用对象克隆。

PHP的under the hood pass object by reference在这里起作用

简而言之,PHP自然地通过引用传递对象,这包括数组成员。如果要对此进行证明,请尝试以下脚本:

<?php $arr = array(new stdClass()); var_dump($arr[0]); $arr2 = $arr; var_dump($arr[0]); ?>
在这两种情况下,输出都将是objectstdClass[1]


有几个解决方案可供您使用。例如,可以对对象使用克隆操作符。如果您知道数组的结构,那么这很简单。如果不这样做,就会出现问题,因为PHP无法克隆数组,因此需要递归地遍历它。所有其他解决方案都包括在编辑对象数据之前复制对象数据。

PHP的“引擎盖下通过引用传递对象”在这里起作用

简而言之,PHP自然地通过引用传递对象,这包括数组成员。如果要对此进行证明,请尝试以下脚本:

<?php $arr = array(new stdClass()); var_dump($arr[0]); $arr2 = $arr; var_dump($arr[0]); ?>
在这两种情况下,输出都将是objectstdClass[1]


有几个解决方案可供您使用。例如,可以对对象使用克隆操作符。如果您知道数组的结构,那么这很简单。如果不这样做,就会出现问题,因为PHP无法克隆数组,因此需要递归地遍历它。所有其他解决方案包括在编辑对象数据之前复制对象数据。

您有权在类上实现新接口吗?如果您这样做,您可以从SPL实现一个接口,让您像在数组中一样迭代对象;如果您有权访问该类并可以实现它,请告诉我,我会给您写一个答案。您有权在该类上实现新接口吗?如果您这样做,您可以从SPL实现一个接口,让您像在数组中一样迭代对象;如果您确实有权访问该类并可以实现它,请告诉我,我会给您写一封信作为我的答案。