84

I come from python background and the python datatype which is similar (a dictionary) is an unordered set of key value pairs.

I am wondering if PHP associative arrays are unordered? They appear to be ordered.

$test = array(
  'test' => 'test',
  'bar' => 'bar',
);

var_dump($test);    

var_dump(array_slice($test, 0, 1));

Test always comes before bar and I can slice this array as you see. So is this always guaranteed to be ordered across php versions? Is the order just the order that I have declared the array with? So something is internally pointing 'test' to place [0] in the array? I have read http://php.net/manual/en/language.types.array.php but it doesn't shed too much light on this issue. I appreciate your responses. Ty

schlamar
  • 9,238
  • 3
  • 38
  • 76
dm03514
  • 54,664
  • 18
  • 108
  • 145
  • 13
    Several of these answers refer to the PHP manual which states that arrays are ordered. But this doesn't answer the original question at all. What was being asked was what the (default) order ***is***! The default order *appears* to be the order in which the elements are assigned, but where does the documentation state that we can count on this from one version to the next? – flymike Jul 03 '16 at 15:39
  • 6
    I raised an issue about lack of documentation at https://bugs.php.net/bug.php?id=76119 and it turns out that the order is always the order the keys were added to the array (changing only value of an array element does not change order of the array). The language spec can be found at https://github.com/php/php-langspec/blob/master/spec/12-arrays.md – Mikko Rantalainen Mar 26 '18 at 13:06
  • 1
    In Python3.6 and above they are ordered. – Bob Aug 03 '20 at 12:34

5 Answers5

80

PHP associative arrays (as well as numeric arrays) are ordered, and PHP supplies various functions to deal with the array key ordering like ksort(), uksort(), and krsort()

Further, PHP allows you to declare arrays with numeric keys out of order:

$a = array(3 => 'three', 1 => 'one', 2 => 'two');
print_r($a);

Array
(
    [3] => three
    [1] => one
    [2] => two
)
// Sort into numeric order
ksort($a);
print_r($a);
Array
(
    [1] => one
    [2] => two
    [3] => three
)

From the documentation:

An array in PHP is actually an ordered map. A map is a type that associates values to keys. This type is optimized for several different uses; it can be treated as an array, list (vector), hash table (an implementation of a map), dictionary, collection, stack, queue, and probably more. As array values can be other arrays, trees and multidimensional arrays are also possible.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390
12

The documentation states:

An array in PHP is actually an ordered map.

So yes, they are always ordered. Arrays are implemented as a hash table.

alexn
  • 57,867
  • 14
  • 111
  • 145
  • 1
    of course I read the first sentance but i was still confused. I realize that if I have an $test = array('foo', 'bar') it is ordered $test[0] is foo, $test[1] is bar. But when I have an associative array the keys are not numerically ordered. $test['test'] is now in first place but it is not numerically indexed it is indexed by a string, that is why I was confused and posted. – dm03514 Jun 06 '12 at 13:05
  • 1
    @dm03514 I'm not sure i get you. But all arrays in PHP are actually associative arrays. Hope that helps. – alexn Jun 06 '12 at 13:07
  • @mikegreiling agreed, changed. Thanks! – alexn Sep 30 '15 at 08:32
3

From the php manual:

Arrays are ordered. The order can be changed using various sorting functions. See the array functions section for more information.

I have relied on the fact that they are ordered and it has worked consistently in every project I've had.

John Weisz
  • 30,137
  • 13
  • 89
  • 132
Mihai Stancu
  • 15,848
  • 2
  • 33
  • 51
3

The array is ordered but that does not mean the keys are sorted, it means that they are in a given order. Where the precise order is not specified, but it appears to be the order in which you introduced the key-value pairs in it.

To understand it, think what would it mean to not be ordered? Well think to a relation in a relational database. A relation is not intrinsically ordered: when you access it with a query the database, unless you provide an order clause, can return the same data in any order. Even if the data was not modified the same data can be returned in different order.

user1708042
  • 1,740
  • 17
  • 20
-1

This is not simple question. The documentation in this case suggests non-obvious points in development, for example:

$a = [0 => 'first', 1 => 'second', 3 => 'fourth'];
$a[2] = 'third';
foreach ($a as $element) print($element . "\n");

Common sense tells us that when iterating this array, we'll see 'third' as the third element, but this is not true:

first
second
fourth
third

Because the elements are stored in the order they have been added, and 0-1-2-3 its just a key, not order. In common, documentation assumes that the elements of an array have some order, which is explicitly stated in the documentation, that means that you van acces to: first element, n-element, last element. But it is not clearly possible to operate them directly. That is, you can get the last element, add to the end (push/pop), you can get the first - shift, you can iterate over them (foreach), but you can't get the n-element without any code or place an element in a certain position without additional code. Well, the question is - how can we rely on this order, if it is required for any reason.

Greenkey
  • 39
  • 1
  • 8
  • 1
    The code you've shared does not use an associative array after all, as it uses numeric indexes – Nico Haase May 11 '23 at 12:03
  • 1
    @NicoHaase actually it IS associative – Your Common Sense May 11 '23 at 12:06
  • it doesn't make this answer any better though. Whether we can access n-th element of associative array is a different question (many times answered by the way) which is unrelated to "whether associative arrays ordered" – Your Common Sense May 11 '23 at 12:11
  • This answer is little more about ordering in PHP arrays. Yes, we can choose nth-element (slice for example), but there is some logical problem, so you must keep in mind that: $a[2] not the same array_slice($a, 2, 1). Key is not related to the order. – Greenkey May 11 '23 at 13:52
  • If `foreach ($yourarray as $key => $value) {/*...*/}` is processing reliably the same key-value pairs, even if (3, 'fourth') comes before (2, 'third'), then the array is ordered. Your point refers to the assumption that numeric indexes determine the order, yet, the order (as you also pointed out) refers to the order the elements were added to the array. Hence, PHP associative arrays are ordered, albeit not necessarily consistently with their numeric indexes. – Lajos Arpad May 13 '23 at 13:41
  • Sure! I understand. My comment is about a logical inconsistency in the concept of an array in PHP. – Greenkey May 16 '23 at 05:50