php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #76119 Order of array after modification is not defined
Submitted: 2018-03-20 13:19 UTC Modified: 2018-03-20 15:24 UTC
From: mikko dot rantalainen at peda dot net Assigned:
Status: Open Package: Arrays related
PHP Version: 7.2.3 OS: Ubuntu Linux 16.04 LTS 64 bit
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2018-03-20 13:19 UTC] mikko dot rantalainen at peda dot net
Description:
------------
---
From manual page: http://www.php.net/language.types.array
---

As evidenced by comments in the manual (documentation) and e.g. https://stackoverflow.com/q/10914730/334451 official PHP documentation does not define order of an array after modifying the array using following syntaxes ($a is assumed to be array with some existing data):

$a["previously-unused-key"] = "test1";
$a[] = "test2";

According to https://3v4l.org/ZTB9c all PHP implementations since PHP 4.3.0 append "test1" and "test2" as the last items of the array $a. However, documentation does not say if this can be trusted in future versions.

The documentation should explicitly say that the behavior is undefined (resulting array order cannot be trusted for future versions), or it should explicitly say that using syntax $a["unused-key"] = 1 will append a new key-value pair as the last item in the array. (First example after subtitle "Examples" in the manual seems to suggest that this is by design but this needs to be spelled out.)

The documentation should also do the same for the case where the key is identical to already used key. It seems that the value is replaced in-place and the order stays intact. If this is by design, it must be spelled out.

The way documentation is currently written, neither of these cases can be trusted to behave the same in the future. (Note that missing documentation is about the order of the array, not about keys or values.)

Is the test script guaranteed to output the actual results in the future, too?

Test script:
---------------
<?php
$a = array(1 => 1, 'c'=>2, 'b'=>3, 'd'=>4);
$a[] = "first value with implicit key";
unset($a['c']);
$a['a'] = "new a";
$a[] = "second value with implicit key";
$a['b'] = "replaced b";
var_export($a);

Expected result:
----------------
(Currently undefined, hopefully actual result is the expected result in future, too.)

Actual result:
--------------
array (
  1 => 1,
  'b' => 'replaced b',
  'd' => 4,
  2 => 'first value with implicit key',
  'a' => 'new a',
  3 => 'second value with implicit key',
)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-03-20 15:24 UTC] requinix@php.net
-Package: Documentation problem +Package: Arrays related
 [2018-03-20 15:24 UTC] requinix@php.net
Given that "an array in PHP is actually an ordered map" (literally the first sentence on the page) then yes, the behavior can be trusted.

It is also spelled out in the language spec:
> The order of the elements in the map is the order in which the elements were inserted into the array.
https://github.com/php/php-langspec/blob/master/spec/12-arrays.md
 [2018-03-26 13:01 UTC] mikko dot rantalainen at peda dot net
I know that the documentation already says "an array in PHP is actually an ordered map". However, that does not say anything about the actual order. That only declares that the order is stable in some way (= order will not randomly change and it's possible to iterate through the array in this order).

The language spec is a bit better (thanks for pointing to it, I didn't know about that repo at all) but even that uses unclear wording:

"The order of the elements in the map is the order in which the elements were inserted into the array."

Given that I can say

(1) $a[] = ...;
(2) $a["existing key"] = ...;
(3) $a["a new key"] = ...;

the wording leaves open if any or all of the cases 1, 2 and 3 are about "inserting the element". The spec clearly says what is considered as "extending" an array but "inserting" an element is not clearly defined. I would suggest re-wording the spec around always extending array with a new element and starting with an empty array. I personally no longer need such explanation as I understand the intent but I would assume that future readers of the documentation and referenced language spec will feel this part unclear.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sun Jun 16 14:01:27 2019 UTC