Hello.Typecasting on the index passed to ArrayObject::offsetGet and ArrayObject::offsetSet seems to be the reason of ArrayObject's confusing behavior on x86 systems.
According to http://php.net/manual/en/language.types.integer.php#language.types.integer.overflow,
If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a float instead. Also, an operation which results in a number beyond the bounds of the integer type will return a float instead.
So, integer is casted to float, then it's passed to ArrayObject::offsetSet and is casted back to integer, probably due to the following lines (ext/spl/spl_array.c:348):
if (offset->type == IS_DOUBLE) { index = (long)Z_DVAL_P(offset); } else { index = Z_LVAL_P(offset); }As a result of calling ArrayObject::offsetSet(index, value) on x86 with a float index exceeds 'long', value appears under a non-obvious index and is replaced on every other call with greater than 'long' index.
Tests are attached. test_array.phpt is passed on both x86 and x86_64, test_array_object.phpt fails to pass on x86 (but is passed on x86_64). This difference in array's and ArrayObject's behavior made me to consider this a bug.
array_object_error.php on x86 just makes pretty clear the reason of fail (see notices PHP throws).
--TEST-- test 1 --FILE-- <?php //$array = new ArrayObject; $array = array(); $key1 = 1e9; $key2 = $key1 * 10; $key3 = $key2 + 1; $array[$key1] = "a"; $array[$key2] = "b"; $array[$key3] = "c"; echo $array[$key1],$array[$key2],$array[$key3]; --EXPECT-- abc
--TEST-- test 1 --FILE-- <?php $array = new ArrayObject; //$array = array(); $key1 = 1e9; $key2 = $key1 * 10; $key3 = $key2 + 1; $array[$key1] = "a"; $array[$key2] = "b"; $array[$key3] = "c"; echo $array[$key1],$array[$key2],$array[$key3]; --EXPECT-- abc
<<attachment: array_object_error.php>>
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php