Doc #81692 [Ver]: array_unique bug with mixed scalar values

From: Date: Mon, 06 Dec 2021 07:10:03 +0000
Subject: Doc #81692 [Ver]: array_unique bug with mixed scalar values
References: 1  Groups: php.doc.bugs 
Request: Send a blank email to doc-bugs+get-19359@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=81692&edit=1

 ID:                 81692
 User updated by:    stanislav dot eismont at gmail dot com
 Reported by:        stanislav dot eismont at gmail dot com
 Summary:            array_unique bug with mixed scalar values
 Status:             Verified
 Type:               Documentation Problem
 Package:            Arrays related
 Operating System:   ubuntu 20.04
 PHP Version:        7.4.26
 Block user comment: N
 Private report:     N

 New Comment:

Hmm, okay, thanks for the explanation. Now I realize that despite the possibility to fix
array_unique(), for example, by choosing a different algorithm, the problem will still exist in
sort() with the SORT_REGULAR flag. Unfortunately, I don't know what to do about it.


Previous Comments:
------------------------------------------------------------------------
[2021-12-03 15:58:57] requinix@php.net

> If you change this array somehow,

Changing the array will change the exact sequence of comparison operations that PHP performs in
order to sort the array (which it needs to achieve the O(log n) efficiency that @cmb mentioned). The
change may result in the two "red"s sorting consecutively, allowing array_unique to
correctly deduplicate them, or it may not.

The problem is in how SORT_REGULAR works - but it's also behaving as intended. The solution is
to not use SORT_REGULAR when you have arrays containing mixed scalars.

------------------------------------------------------------------------
[2021-12-03 15:47:50] stanislav dot eismont at gmail dot com

To me it isn't look like a doc related problem. I gave such a big array as an example for a
reason. If you change this array somehow, let's say remove last element, then there will be one
"red" value printed https://3v4l.org/tpjMt.

------------------------------------------------------------------------
[2021-12-03 15:30:54] cmb@php.net

> Isn't this just a result of inconsistent comparisons during
> sorting?

Right, although PHP 5 produced the required results[1].

Anyhow, SORT_REGULAR has a fundamental flaw when working on
arbitrarly mixed scalar types, namely that the result is not
necessarily in monotonic order, i.e. the sort has arbitrary
results (depending on the sorting algorithm).  E.g. consider ['2',
'a', 1]; the following holds prior to PHP 8.0.0:

    '2' < 'a'
    'a' < 1
    '2' > 1

As of PHP 8.0.0, this is no longer the case for the given example
(thanks to the saner string to number comparisons), but consider
another example: ['!', '0', true]; the following holds:

    '!' < '0'
    '0' < true
    '!' == true

That still doesn't work.

So the current O(log n) algorithm of array_unique(), would need to
be changed to an O(n²) algorithm, or the sorting algorithm would
need to be changed back to what we had in PHP 5.  Neither option
is desireable, and I think we should just document this
limitation.  (And we also should fix the note in the description
section, which only applies for SORT_STRING.)

[1] <https://3v4l.org/RfFJr>

------------------------------------------------------------------------
[2021-12-03 15:13:58] requinix@php.net

Isn't this just a result of inconsistent comparisons during sorting? The sorted arrays
don't place the two reds next to each other with SORT_REGULAR; they do if you use SORT_STRING,
which also produces the expected unique array.
https://3v4l.org/JTQMr
https://3v4l.org/gPaPn

------------------------------------------------------------------------
[2021-12-03 12:25:04] cmb@php.net

Indeed, broken as of PHP 7.0.0: <https://3v4l.org/PXQZe>.

------------------------------------------------------------------------


The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at

    https://bugs.php.net/bug.php?id=81692


--
Edit this bug report at https://bugs.php.net/bug.php?id=81692&edit=1


Thread (6 messages)

« previous php.doc.bugs (#19359) next »