One key. Almost 3 MiB more.
$ids = range(0, 99_999);// keys 0 to 99_999 are implied$ids['100000'] = true;$ids['meta'] = true;$result = ['ids' => $ids, 'meta' => true];
2.02 MiB. A packed list. The values sit in a row, and the keys are just their positions.
2.02 MiB. Still packed. PHP reads '100000' as the integer 100000, the next index, and the array already had room for it.
5.00 MiB. A hash table now. Every value moved into a bigger slot that also stores a key, and memory peaked at 7.02 MiB while both copies existed.
2.02 MiB. The list stays packed. The two-key wrapper around it adds 376 bytes.
PHP 8.4.19, 64-bit arm64. Memory above a baseline from memory_get_usage(false), the same in three fresh runs per case.
A string key that PHP can’t read as an integer turns a packed list into a hash table, and every value pays for it. Keep the flag beside the list instead, though callers then get a wrapper rather than a bare list.
Read the original post