Comparison and the Spaceship <=>

Loose vs strict comparison, the PHP 8 rule change for string/number comparisons, and using <=> to write clean sorts.

Two things every senior PHP dev keeps in muscle memory. First: use === by default. Second: PHP 8 fixed a decade-old footgun — 0 == "foo" is now false (pre-8 it was true). A number compared to a non-numeric string now converts the number to a string, which is what you actually want.

The spaceship operator

<=> returns -1, 0, or 1 — perfect for the callback usort() expects.

<?php
echo 1 <=> 2; // -1
echo 5 <=> 5; //  0
echo 9 <=> 3; //  1

It works on strings, arrays and objects too, comparing element by element.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Use <=> as the usort comparator to sort user records by last name then first name in one expression.
  • Replace a verbose if/elseif chain for three-way comparisons with a single spaceship expression.
  • Rely on strict === in a match expression to avoid the falsy-zero trap when comparing database return values.

More examples

Loose vs strict equality gotcha

PHP 8 changed string-int loose comparison (0 == 'foo' is now false), but === always remains unambiguous.

Example · php
<?php
var_dump(0    == 'foo');   // true  (PHP 7: 'foo' cast to 0)
var_dump(0    === 'foo');  // false (strict: int vs string)
var_dump('1'  == true);   // true
var_dump('1'  === true);  // false

Spaceship for multi-key sort

Comparing arrays with <=> gives lexicographic ordering across multiple keys in a single clean expression.

Example · php
<?php
$users = [
    ['last' => 'Smith',  'first' => 'Bob'],
    ['last' => 'Smith',  'first' => 'Alice'],
    ['last' => 'Archer', 'first' => 'Zara'],
];

usort($users, function ($a, $b) {
    return [$a['last'], $a['first']] <=> [$b['last'], $b['first']];
});

foreach ($users as $u) {
    echo "{$u['last']}, {$u['first']}\n";
}

Three-way result with spaceship

<=> combined with match elegantly maps the -1/0/1 result to human-readable labels.

Example · php
<?php
function compareVersions(string $a, string $b): string {
    return match(version_compare($a, $b) <=> 0) {
        -1 => "$a is older",
         0 => "Same version",
         1 => "$a is newer",
    };
}

echo compareVersions('8.2.0', '8.1.9'); // 8.2.0 is newer

Discussion

  • Be the first to comment on this lesson.