Bug #69866 [Nab]: usort call with same keys problem
| From: | requinix@php.net | Date: | Thu, 18 Jun 2015 06:52:53 +0000 |
| Subject: | Bug #69866 [Nab]: usort call with same keys problem | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-193639@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=69866&edit=1
ID: 69866
Updated by: requinix@php.net
Reported by: dmifedorenko at gmail dot com
Summary: usort call with same keys problem
Status: Not a bug
Type: Bug
Package: Arrays related
Operating System: Linux vm 3.13.0-37-generic #64-U
PHP Version: 7.0Git-2015-06-18 (Git)
Block user comment: N
Private report: N
New Comment:
Unfortunately yes. Try with different sizes of arrays and the items in different orders and
you'll see the result vary.
PHP 7 will bring a number of big internal changes, and apparently those influenced usort() which I
say because I don't know of any deliberate changes to it, but the fact is that your code was
relying on undefined behavior.
Previous Comments:
------------------------------------------------------------------------
[2015-06-18 06:09:31] dmifedorenko at gmail dot com
Thank you for the answer.
We have a lot of code in our project. Of course we can fix some fallen unit tests, but due to the
fact that this code _always_ worked stable in 5.5 and 5.6 is necessary to review all 84 cases using
usort in our project.
Perhaps some of them expect the old behavior and will have problems with PHP7.
Are you sure this is our problem and not backward compatible issue?
------------------------------------------------------------------------
[2015-06-18 05:42:32] requinix@php.net
usort() does not produce stable results if the comparison function is inconsistent. Your function
claims that both items in $result should sort after the other so you'll get different results
with different initial orders.
If you make your function behave properly then not only will you get the "right" result
but you'll get it in every version of PHP. For example, you could do
return $b[1] - $a[1];
Note that sorting this way will claim both items are equal and, just like what happens with an
inconsistent comparison function, their sort order will be undefined and thus vary with the initial
ordering.
Obviously if you took both numbers into consideration then that wouldn't happen:
return ($b[1] - $a[1]) ?: ($b[0] - $a[0]);
------------------------------------------------------------------------
[2015-06-18 03:45:40] dmifedorenko at gmail dot com
Description:
------------
Different usort behavior in php5.6 and php7.
5.6 returns first array element, and 7 returns last element.
Test script:
---------------
$results = array(
array(2001, 1),
array(2002, 1),
);
usort($results, function ($a, $b) {
return $a[1] > $b[1] ? -1 : 1;
});
var_dump($results[0][0]);
Expected result:
----------------
int(2001)
Actual result:
--------------
int(2002)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=69866&edit=1