Search code examples
phpsymfonyassociative-arraysymfony3.xordered-map

Why does Symfony provide an OrderedHashMap


Symfony provides an OrderedHashMap. Its documentation states

Unlike associative arrays, the map keeps track of the order in which keys were added and removed. This order is reflected during iteration.

I'm confused by this statement, because I thought PHP associative arrays are actually already ordered maps. I found this question on SO, which confirms my previous assumption: Are PHP Associative Arrays ordered?

I wonder, if the Symfony devs didn't know PHP arrays are already ordered maps or if I don't understand the role of Symfony's OrderedHashMap


Solution

  • Of course PHP's array is an ordered-map.

    But Symfony's OrderedHashMap has some different behaviors (say, features) from PHP's array.

    OrderedHashMap supports concurrent modification during iteration. That means that you can insert and remove elements from within a foreach loop and the iterator will reflect those changes accordingly. But array in the iteration is a copied one (Copy-On-Write), any modification is not reflected in the loop.

    $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;
        }
    }
    

    You will get different output if you are using array. In the iteration of an array the loop won't see the number 5.

    About "Why?": Search it in Symfony's codebase. There is only one place to use the OrderedHashMap, which is used to store a form's children. It's used by new InheritDataAwareIterator($this->children) to iterate. So I think the answer is to help to process the form's children.

    And thanks to @fishbone:

    So the benefit is not the ordering but the ability to modify it in loops.