Array comparison works completely different than documented?

  116547
December 1, 2021 13:56 andre@webkr.de (=?iso-8859-1?Q?Andr=E9_H=E4nsel?=)
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 and FALSE 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?
  116548
December 1, 2021 14:19 george.banyard@gmail.com ("G. P. B.")
On Wed, 1 Dec 2021 at 13:56, André Hänsel <andre@webkr.de> wrote:

> 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 > <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 and FALSE 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? > > -- > PHP Internals - PHP Runtime Development Mailing List > 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
  116549
December 1, 2021 14:59 cmbecker69@gmx.de ("Christoph M. Becker")
On 01.12.2021 at 14:56, André Hänsel wrote:

> 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 and FALSE 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
  116552
December 1, 2021 23:24 benjamin.morel@gmail.com (Benjamin Morel)
> > 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
  116567
December 5, 2021 00:43 jordan.ledoux@gmail.com (Jordan LeDoux)
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