【问题标题】:Reconstructing PHP Array of Repeated Objects With New Value用新值重建 PHP 重复对象数组
【发布时间】:2016-04-04 22:23:33
【问题描述】:

在解决我认为是一项直截了当的任务的太多小时之后,我相信我要么错过了一个明显的缺陷,要么已经构建了一个错误的心理模型来说明它应该如何工作。

我的实际数据要复杂得多,但我已将其简化为这个示例。

假设我有一个对象数组$my_array

$object1 = new stdClass();
    $object1->valueA = 'abc';
    $object1->valueB = 'def';
    $object1->valueC = '20160410';
$object2 = new stdClass();
    $object2->valueA = '123';
    $object2->valueB = '456';
    $object2->valueC = '20160408';
$object3 = new stdClass();
    $object3->valueA = 'foo';
    $object3->valueB = 'bar';
    $object3->valueC = '20160412';

$my_array = array(
    'X' => $object1,
    'Y' => $object2,
    'Z' => $object3
);

我想遍历每个对象,使用其中一个值来计算新属性,然后将对象分配给新数组,使用新的计算值对它们进行分组。

我是这样做的:

$new_array= array();
foreach($my_array as $key=>$obj){
    for($i=0;$i<=2;$i++){  //the real use case uses a slightly different loop, this is simpler/shorter for an example 
        $date = $obj->valueC + $i;  //use valueC and the loop to calculate a new value
        $obj->date = $date;  //add my new value to the object
        $new_array[$date][$key] = $obj;  //construct new array of arrays of objects. bits on bits on bytes.
    }
}

如果我将结果数组记录到控制台,它看起来像这样:

[04-Apr-2016 22:09:28 UTC] Array
(
    [20160410] => Array
        (
            [X] => stdClass Object
                (
                    [valueA] => abc
                    [valueB] => def
                    [valueC] => 20160410
                    [date] => 20160412
                )

            [Y] => stdClass Object
                (
                    [valueA] => 123
                    [valueB] => 456
                    [valueC] => 20160408
                    [date] => 20160410
                )

        )

    [20160411] => Array
        (
            [X] => stdClass Object
                (
                    [valueA] => abc
                    [valueB] => def
                    [valueC] => 20160410
                    [date] => 20160412
                )

        )

    [20160412] => Array
        (
            [X] => stdClass Object
                (
                    [valueA] => abc
                    [valueB] => def
                    [valueC] => 20160410
                    [date] => 20160412
                )

            [Z] => stdClass Object
                (
                    [valueA] => foo
                    [valueB] => bar
                    [valueC] => 20160412
                    [date] => 20160414
                )

        )

    [20160408] => Array
        (
            [Y] => stdClass Object
                (
                    [valueA] => 123
                    [valueB] => 456
                    [valueC] => 20160408
                    [date] => 20160410
                )

        )

    [20160409] => Array
        (
            [Y] => stdClass Object
                (
                    [valueA] => 123
                    [valueB] => 456
                    [valueC] => 20160408
                    [date] => 20160410
                )

        )

    [20160413] => Array
        (
            [Z] => stdClass Object
                (
                    [valueA] => foo
                    [valueB] => bar
                    [valueC] => 20160412
                    [date] => 20160414
                )

        )

    [20160414] => Array
        (
            [Z] => stdClass Object
                (
                    [valueA] => foo
                    [valueB] => bar
                    [valueC] => 20160412
                    [date] => 20160414
                )

        )

)

现在,我希望 $new_array['20160410']['X']->date 是 20160410。毕竟,在两行之内,我说过,“使用这个值作为顶级数组键,也作为对象中的值”。但无论我做什么,['X'] 的所有实例都将具有相同的date 值。 ['Y']['Z'] 相同。

我的目标是能够将新计算的date 值存储在对象中,同时将该值用作分组键。

【问题讨论】:

  • 您开始注意到数组中每个对象的所有值都是相同的。下一步是检查您在代码中使用的所有内容的手册。
  • 如果数据在关系数据库中,这将是微不足道的。

标签: php arrays sorting object


【解决方案1】:

默认情况下,对象通过引用分配,您可以在manual 中阅读它:

经常提到的PHP 5 OOP的一个关键点是“对象默认通过引用传递”

所以你可以想象你在 for 循环中的赋值:

$new_array[$date][$key] = $obj;

像这样:

$new_array[$date][$key] = &$obj;
                          ↑

这意味着您将在 for 循环的每次迭代中更新所有对象。要解决这个问题,只需 clone 对象,例如

$new_array[$date][$key] = 克隆 $obj;

【讨论】:

  • 哇 - 你刚刚澄清了我对对象的长期误解,我可以立即看到它们在许多我以前没有考虑过的方面是如何有用的。我只希望我在 2 天前发布此内容,然后再花这么多时间进行调试!下一次,也许我会尝试 ole RTFM 方法。谢谢!
  • @AndrewCafourek 长时间调试也不是什么坏事。也许下次只需开始阅读有关您在代码中使用的所有内容的手册;)
猜你喜欢
  • 1970-01-01
  • 2021-07-23
  • 2020-02-27
  • 2017-05-07
  • 1970-01-01
  • 2021-12-21
  • 2019-01-16
  • 2022-11-24
  • 2021-03-11
相关资源
最近更新 更多