I’m trying to use usort on an array, and get a different behavior regarding the version of PHP:
$arr1 = [
[
'points' => 10,
'date' => 3,
],
[
'points' => 10,
'date' => 2,
],
[
'points' => 10,
'date' => 1,
]
];
usort($arr1, function ($a, $b) {
if($a['points'] == $b['points']){
return 0;
}
return ($a['points'] < $b['points']) ? 1 : -1;
});
This array contains a “date” value, and is ordered DESC on this value, after the usort based on a “points” value, items with the same “points” value are reversed on PHP 5.6, and keep their original order on PHP 7.0…
You may test this online here, with the different PHP versions (please test against PHP 5.6.29 and 7.0.1): http://sandbox.onlinephpfunctions.com/code/2715220539623b4b699ebb3f90a4b01c98eef53d
How could I get the same sorting behavior on equal points under any PHP version?
3
Answers
If you want to have the same results in both versions, you will need to ensure that you specify how equal items will deal with other fields.
So you could solve this with…
So if the
points
value is the same, then usedate
as the differentiator (assuming a numeric comparison would work.)As others have already noted, you need to sort on more than one key. PHP provides for this through its
compare_func
callable, and it also provides the<=>
*(“spaceship”) operator for your convenience in writing such functions.If your
compare_func
finds thatpoints
is equal, it should proceed to comparedate
and so on, returning the first value that isn’t zero. (You can use theor
operator to do this.)And, if all of the sort-keys are equal, the behavior of
usort()
is “unpredictable.” In this case, you should not presume that the records will be presented in any particular order … even from one call tousort()
to the next. If you think that “this version of PHP ‘always’ does it this way, and that version ‘always’ does it some other way,” assume that you are merely mistaken.