PHP7: spaceship operator

В ПХП7 вошёл новый оператор — «космический корабль». Я его помню со времён программирования на Перле. Наиболее частое применение он, по всей видимости, найдёт в сортировках:

usort($data, function ($o1, $o2) {
    return $o1->value <=> $o2->value;
});

Комбинация «меньше», «равно» и «больше» — и есть «космический корабль». Результат его выполнения следующий — если левое меньше, получается «-1», если правое — «1», если значение равны, вернётся ноль. Для строк уже сейчас (с чётвертой версии языка) существует функция strcmp, которая делает то же.

Новый оператор сравнивает даже массивы и объекты, в RFC есть соответствующие примеры:

echo [1, 2, 3] <=> [1, 2, 1]; // 1
echo [1, 2, 3] <=> [1, 2, 4]; // -1

$a = (object) ["a" => "b"];
$b = (object) ["a" => "c"];
echo $a <=> $b; // -1
 
$a = (object) ["a" => "c"];
$b = (object) ["a" => "b"];
echo $a <=> $b; // 1
 
// only values are compared
$a = (object) ["a" => "b"];
$b = (object) ["b" => "b"];
echo $a <=> $b; // 0

В общем, какой-то особенной пользы в язык конструкция не принесёт, но в в неких частных случаях читаемость улучшится.

Комментарии 8

Svan № 7
Хотя…
Например, промежутки дат:
дата начала больше даты финиша — ошибка
дата начала совпадает с датой финиша — нормально, обработать одним образом
дата начала меньше даты финиша — нормально, обработать другим образом.
Денис Радченко № 8

Не знал, что можно сравнивать массивы. Теперь вместо

return ($a['order'] $b['order']) ?: ($a['name'] $b['name'])

буду писать

return [$a['order'], $a['name']] [$b['order'], $b['name']];