The official documentation contains a conceptual description of array
comparison in
https://www.php.net/manual/en/language.operators.comparison.php#example-113.
Curiously the people who wrote the inofficial spec (I think the HHVM team at
Facebook?) came to
pretty much the same result, described in
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#relat
ional-operators:
If both operands have array type, if the arrays have different numbers of
elements, the one
with the fewer is considered less-than the other one, regardless of the
keys and values in each,
and the comparison ends. For arrays having the same numbers of elements,
the keys from the left
operand are considered one by one, if the next key in the left-hand
operand exists in the
right-hand operand, the corresponding values are compared. If they are
unequal, the array
containing the lesser value is considered less-than the other one, and the
comparison ends;
otherwise, the process is repeated with the next element. If the next key
in the left-hand
operand does not exist in the right-hand operand, the arrays cannot be
compared andFALSE
is
returned. If all the values are equal, then the arrays are considered
equal.
In reality, array comparison works completely different, it is however
unclear to me how exactly
it does work: https://3v4l.org/630vG
Do we know how this happened?
The official documentation contains a conceptual description of array
comparison in
https://www.php.net/manual/en/language.operators.comparison.php#example-113
.Curiously the people who wrote the inofficial spec (I think the HHVM team
at
Facebook?) came to
pretty much the same result, described inhttps://github.com/php/php-langspec/blob/master/spec/10-expressions.md#relat
ional-operators
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#relational-operators
:If both operands have array type, if the arrays have different numbers of
elements, the one
with the fewer is considered less-than the other one, regardless of the
keys and values in each,
and the comparison ends. For arrays having the same numbers of elements,
the keys from the left
operand are considered one by one, if the next key in the left-hand
operand exists in the
right-hand operand, the corresponding values are compared. If they are
unequal, the array
containing the lesser value is considered less-than the other one, and
the
comparison ends;
otherwise, the process is repeated with the next element. If the next key
in the left-hand
operand does not exist in the right-hand operand, the arrays cannot be
compared andFALSE
is
returned. If all the values are equal, then the arrays are considered
equal.In reality, array comparison works completely different, it is however
unclear to me how exactly
it does work: https://3v4l.org/630vGDo we know how this happened?
--
To unsubscribe, visit: https://www.php.net/unsub.php
It seems the docs are not accurate in that it will not try to find the
corresponding element in the second array.
By rearranging the keys to be defined in the same order the docs seems to
match the corresponding behaviour: https://3v4l.org/2ta2k
The actual C code implementation of how the arrays are compared (after some
symbol navigation) is the zend_hash_compare_impl() function.
https://heap.space/xref/php-src/Zend/zend_hash.c?r=d3f073e8#2919
Hope this helps.
Best regards
George P. Banyard
The official documentation contains a conceptual description of array
comparison in
https://www.php.net/manual/en/language.operators.comparison.php#example-113.Curiously the people who wrote the inofficial spec (I think the HHVM team at
Facebook?) came to
pretty much the same result, described in
https://github.com/php/php-langspec/blob/master/spec/10-expressions.md#relat
ional-operators:If both operands have array type, if the arrays have different numbers of
elements, the one
with the fewer is considered less-than the other one, regardless of the
keys and values in each,
and the comparison ends. For arrays having the same numbers of elements,
the keys from the left
operand are considered one by one, if the next key in the left-hand
operand exists in the
right-hand operand, the corresponding values are compared. If they are
unequal, the array
containing the lesser value is considered less-than the other one, and the
comparison ends;
otherwise, the process is repeated with the next element. If the next key
in the left-hand
operand does not exist in the right-hand operand, the arrays cannot be
compared andFALSE
is
returned. If all the values are equal, then the arrays are considered
equal.In reality, array comparison works completely different, it is however
unclear to me how exactly
it does work: https://3v4l.org/630vG
The point is that $a > $b is actually checking whether $b <= $a. This
is fine for ordered values, but these arrays are not orderable
(according to PHP's comparison). That might indeed not be documented in
the PHP manual (the language specification appears to be abandoned anyway).
--
Christoph M. Becker
The point is that $a > $b is actually checking whether $b <= $a. This
is fine for ordered values, but these arrays are not orderable
(according to PHP's comparison). That might indeed not be documented in
the PHP manual (the language specification appears to be abandoned anyway).
Shouldn't we throw an exception when comparing arrays with <, <=, >, >=
anyway?
- Benjamin
On Wed, Dec 1, 2021 at 7:00 AM Christoph M. Becker cmbecker69@gmx.de
wrote:
The point is that $a > $b is actually checking whether $b <= $a. This
is fine for ordered values, but these arrays are not orderable
(according to PHP's comparison). That might indeed not be documented in
the PHP manual (the language specification appears to be abandoned anyway).
Are there any tests that capture this? As part of my operator overload RFC
I'm breaking out > into its own opcode instead of a reordered <=, so this
may actually be "fixed" by this. However, I haven't noticed any array
related comparison tests failing in my builds.
Jordan