phparrayssortingusort

Wrong result usort PHP 8


I have the following code which should sort 'BMW' to the first position:

$cars=['Toyota','Volvo','BMW'];
usort($cars,function($v){return $v <=> 'BMW';});
var_export($cars);

The result with PHP7 (and smaller) is correct:

array ( 0 => 'BMW', 1 => 'Volvo', 2 => 'Toyota', )

As far as I understand, the result with PHP8 is wrong.

array (0 => 'Volvo', 1 => 'BMW', 2 => 'Toyota',)

Demo: https://3v4l.org/8SCXk

It's not up to the spaceship operator. This one seems to be working correctly. The cause must lie in the behavior of usort.

var_dump(
    'Volvo' <=> 'BMW',
    'BMW' <=> 'Volvo',
    'BMW' <=> 'Toyota',
    'Toyota' <=> 'BMW',
    'BMW' <=> 'BMW'
    );

Demo: https://3v4l.org/UaKrM

My question: Is this a nasty bug in PHP8 or do I need to change my code?


Solution

  • If you have the wrong callback function, you'll get the wrong result. It should be:

    $cars = ['Toyota', 'Volvo', 'BMW'];
    usort($cars, function ($a, $b) { return $a <=> $b; });
    var_export($cars);
    

    Notice the second parameter $b and how it is used.

    See: usort() and an example here: https://3v4l.org/X1DVU

    The difference you see with older PHP versions is indeed caused by PHP 8 switching to sable sorting, but this is irrelevant in your case.