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).