为什么Symfony提供OrderedHashMap

时间:2018-03-23 08:55:12

标签: php symfony associative-array symfony3.x ordered-map

Symfony提供OrderedHashMap。它的documentation states

  

与关联数组不同,地图会跟踪添加和删除键的顺序。此顺序在迭代期间反映出来。

我对此声明感到困惑,因为我认为PHP关联数组实际上已经是有序映射。我在SO上发现了这个问题,这证实了我之前的假设:Are PHP Associative Arrays ordered?

我想知道,如果Symfony开发人员不知道PHP数组已经是有序的地图,或者我不理解Symfony OrderedHashMap的作用

2 个答案:

答案 0 :(得分:2)

当然PHP的数组是有序映射。

但Symfony的OrderedHashMap在PHP的数组中有一些不同的行为(比如 features )。

OrderedHashMap支持迭代期间的并发修改。这意味着您可以在foreach循环中插入和删除元素,迭代器将相应地反映这些更改。但是迭代中的array是一个复制的( Copy-On-Write ),任何修改都不会反映在循环中。

$map = new OrderedHashMap();
$map[1] = 1;
$map[2] = 2;
$map[3] = 3;

foreach ($map as $index => $value) {
    echo "$index: $value\n"
    if (1 === $index) {
        $map[1] = 4;
        $map[] = 5;
    }
}

如果您使用array,您将获得不同的输出。在array的迭代中,循环将看不到数字5

关于“为什么?”:在Symfony's codebase中搜索。只有一个的地方才能使用OrderedHashMap,用于存储表单的子项。它由new InheritDataAwareIterator($this->children)用于迭代。所以我认为答案是帮助处理表格的孩子。

感谢@fishbone:

  

因此,好处不是排序,而是在循环中修改它的能力。

答案 1 :(得分:0)

一般而言,不仅在Symfony的上下文中,除了其他实现的功能外,面向对象的结构优于intstringarray等基本类型,因为它们可以注入单元测试的类。

面向对象的结构也可以强制执行不变量,而基本类型只能保存数据而不会有任何行为。