> > That might actually be something I could use :) But the fun for me begins > here: > > $numbers = array(); > $numbers[-1] = 5; > $numbers[] = 6; > > What would have happened to the keys? Normally [] is equivalent to > [count($numbers)]. >
This is incorrect, $numbers[] = 6; is not equivalent to $numbers[count($numbers)] = 6; at all, because PHP uses an internal value for this that is represented an unsigned long in the Hashtable ht struct. As it stands today, that code would result in the following: $numbers = array(); $numbers[-1] = 5; $numbers[] = 6; var_dump($numbers); /* array(2) { [-1]=> int(5) [0]=> int(6) } */ Which looks awkward, I know, but the reason is that the internal value that represents the next key to be used when no key is supplied during an array push is an unsigned figure while integer values in PHP are all signed. Since one's complement is used this means the unsigned value will always wrap-around causing -1 to take us back to zero (you can't overflow an unsigned long). Here's how we can see this quirk rearing it's ugly head: $numbers = array(); $numbers[PHP_INT_MAX] = 'foo'; $numbers[] = 'bar'; var_dump($numbers); /* Warning: Cannot add element to the array as the next element is already occupied in ... on line 1 array(1) { [9223372036854775807]=> string(3) "foo" } */ As you can see PHP has a bit of a hickup here. The implementation is such that the index is always initialized to 0 by default and clamped by the API (so when a negative value is supplied we still start back at 0). Here's the actual implementation of array_psuh: for (i = 0; i < argc; i++) { new_var = *args[i]; Z_ADDREF_P(new_var); if (zend_hash_next_index_insert(Z_ARRVAL_P(stack), &new_var, sizeof(zval *), NULL) == FAILURE) { Z_DELREF_P(new_var); php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot add element to the array as the next element is already occupied"); efree(args); RETURN_FALSE; } } $array = array(); $array[PHP_INT_MAX+1] = 'foo'; $array[] = 'bar'; var_dump($array); /* array(2) { [-9223372036854775808]=> string(3) "foo" [0]=> string(3) "bar" } */ Another gotchya, of the API is that the representation of the key used in the array and the next available key can be somewhat two misleading. --- On a final note the confusion behind proposing the use of negative indexes for array lookup in PHP is that PHP doesn't really have an array. Something I believe has been discussed at length in the past. Which is why it makes sense to separate the "key" used in the array from the "offset" of the element in the ordered map. $array = array(-1 => "foo",0 => "bar",3 => "baz") array_slice($array, -1); // makes perfect sense to me that this would return "baz" $array = array(-1 => "foo",0 => "bar",3 => "baz") echo $array[-1]; // makes perfect sense to me that this would return "foo" -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php