Spaceship and Ternary

The Spaceship and Ternary Operators

The spaceship <=> (PHP 7.0) returns -1, 0 or 1 as its left side is less than, equal to or greater than the right, as usort() expects. Arrays compare element by element, so compare two arrays to sort on several keys; swap $x and $y for a key to reverse it. a ?: b yields a if truthy, while a ?? b yields b only when a is null or undefined; ??= (7.4) is covered in Null and Nullables. The nullsafe ?-> (8.0) in the last line ends a chain as null at the first null link instead of throwing an Error.

Sorting on three keys, and the ternary familyPHP
<?php
$books = [['Dune', 'SF', 9.99], ['Emma', 'Classic', 4.50],
    ['Neuromancer', 'SF', 12.00], ['Persuasion', 'Classic', 4.50]];
// Genre ascending, then price descending, then title ascending.
usort($books, fn($x, $y) => [$x[1], $y[2], $x[0]] <=> [$y[1], $x[2], $y[0]]);
echo implode(", ", array_column($books, 0)), "\n";
$nickname = "";
echo $nickname !== "" ? $nickname : "Guest", " | ";   // full ternary
echo $nickname ?: "Guest", " | ";                    // short ternary: any falsy value
echo $nickname ?? "Guest", "|\n";                    // ?? replaces only null or unset
class Customer { public ?Customer $referrer = null; public string $name = 'Ann'; }
echo new Customer()->referrer?->name ?? 'no referrer', "\n";   // null, not an Error
Output
Emma, Persuasion, Neuromancer, Dune
Guest | Guest | |
no referrer

?: tests truthiness, ?? tests for null, so the empty string passes ?? untouched. An unparenthesized nested ternary ($s >= 90 ? "A" : $s >= 70 ? "C" : "F") has been a compile error since PHP 8.0: "Unparenthesized a ? b : c ? d : e is not supported". Use parentheses or match (true) (switch and match).