How Are Associative Arrays Implemented in PHP

How is the PHP array implemented on the C level?

PHP associative arrays are in fact implementation of HashTables.

Internally, it is possible to make numeric arrays or associative arrays.
If you combine them, it is associative array.

In numeric arrays, it is very similar to C. You have array of pointers to ZVAL structs.

Because pointers have fixed-length (let's call it n), the offset (x) calculation is easy: x * n.

In PHP types are ZVAL structs (because that way it implements dynamic types), but it also helps in associative array, because you can assume fixed-length. So even if direct access to array is slower, it is still considered O(1).

So what happens in string keys? PHP uses hash function to convert them to intergers.

Searching in numeric and associative array has similar efficiency, because internally they are all numeric.

Only direct-access to array keys is slower, because of the additional level (hash function).

Hash tables VS associative arrays

In PHP, associative arrays are implemented as hashtables, with a bit of extra functionality.

However technically speaking, an associative array is not identical to a hashtable - it's simply implemented in part with a hashtable behind the scenes. Because most of its implementation is a hashtable, it can do everything a hashtable can - but it can do more, too.

For example, you can loop through an associative array using a for loop, which you can't do with a hashtable.

So while they're similar, an associative array can actually do a superset of what a hashtable can do - so they're not exactly the same thing. Think of it as hashtables plus extra functionality.

Code examples:

Using an associative array as a hashtable:

$favoriteColor = array();
$favoriteColor['bob']='blue';
$favoriteColor['Peter']='red';
$favoriteColor['Sally']='pink';
echo 'bob likes: '.$favoriteColor['bob']."\n";
echo 'Sally likes: '.$favoriteColor['Sally']."\n";
//output: bob likes blue
// Sally likes pink

Looping through an associative array:

$idTable=array();
$idTable['Tyler']=1;
$idTable['Bill']=20;
$idTable['Marc']=4;
//up until here, we're using the array as a hashtable.

//now we loop through the array - you can't do this with a hashtable:
foreach($idTable as $person=>$id)
echo 'id: '.$id.' | person: '.$person."\n";

//output: id: 1 | person: Tyler
// id: 20 | person: Bill
// id: 4 | person: Marc

Note especially how in the second example, the order of each element is maintained (Tyler, Bill Marc) based on the order in which they were entered into the array. This is a major difference between associative arrays and hashtables. A hashtable maintains no connection between the items it holds, whereas a PHP associative array does (you can even sort a PHP associative array).

How does PHP keep track of order in an associative array?

How are associative arrays implemented in PHP? might give you some insight.

It seems that PHP arrays are essentially hash tables, so the order of the array will stay the same until you reorder it (e.g. by sorting the array).

EDIT: It appears this is getting downvoted, allow me to explicitly include the sources I linked to in the comment below here...

  • "PHP associative arrays are in fact an implementation of HashTables", from
    How is the PHP array implemented on the C level?

  • Also from that source: "The PHP array is a chained hash table (lookup of O(c) and O(n) on key collisions) that allows for int and string keys. It uses 2 different hashing algorithms to fit the two types into the same hash key space."

  • "Everything is a HashTable" from http://nikic.github.io/2012/03/28/Understanding-PHPs-internal-array-implementation.html

Are PHP Associative Arrays ordered?

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.

PHP assoc array to class instance

Things are not that easy, since there is no way for php to somehow magically guess what to do with the values of that array. Objects are a structured set of data unlike an array. So you need a description of the structure and rules how to use it.

You need to implement a constructor in the class definition, then you can construct a new object based on some given array. Take a look at this arbitrary example:

<?php
class A {
protected $title;
protected $data;
public function __construct ($data) {
$this->title = $data['title'];
$this->data = sprintf('this is foo: %s', $data['foo']);
}
public function __toString() {
return sprintf(
"I am an object titled '%s'\nI hold that foo value: %s\n",
$this->title,
$this->data
);
}
}

$data = [
'title' => 'hello world',
'foo' => 'foovalue',
'bar' => 'barvalue'
];
$object = new A($data);
echo $object;
var_dump($object);

The obvious output is:

I am an object titled 'hello world'
I hold that foo value: this is foo: foovalue
/home/arkascha/test.php:25:
class A#1 (2) {
protected $title =>
string(11) "hello world"
protected $data =>
string(21) "this is foo: foovalue"
}

Are the key and value terms for hash tables and associative arrays used interchangeably?

"key" and "value" do not mean the same thing.

The key is the thing you feed into a hash table or PHP associative array or, generically, "map" to get back a value.

The confusion you're running into is that the value you get back from the hash table in your first example is then being used as a key (an array index) to a different thing (the array). Just as a person can be both a parent and a child, a number (or whatever) can be both a key (in one thing) and a value (in something else). It's a matter of what its role is in relation to the thing you're using it with.

How to check if PHP array is associative or sequential?

You have asked two questions that are not quite equivalent:

  • Firstly, how to determine whether an array has only numeric keys
  • Secondly, how to determine whether an array has sequential numeric keys, starting from 0

Consider which of these behaviours you actually need. (It may be that either will do for your purposes.)

The first question (simply checking that all keys are numeric) is answered well by Captain kurO.

For the second question (checking whether the array is zero-indexed and sequential), you can use the following function:

function isAssoc(array $arr)
{
if (array() === $arr) return false;
return array_keys($arr) !== range(0, count($arr) - 1);
}

var_dump(isAssoc(['a', 'b', 'c'])); // false
var_dump(isAssoc(["0" => 'a', "1" => 'b', "2" => 'c'])); // false
var_dump(isAssoc(["1" => 'a', "0" => 'b', "2" => 'c'])); // true
var_dump(isAssoc(["a" => 'a', "b" => 'b', "c" => 'c'])); // true


Related Topics



Leave a reply



Submit