haphpiness

These are things in PHP which make me genuinely_happy();

Spaceship Operator <=> — Three-Way Comparison

PHP 7.0 introduced <=>: it returns -1, 0, or 1 depending on whether the left side is less than, equal to, or greater than the right. This is exactly what usort comparators need.

// Before: manual if/else dance
usort($users, function ($a, $b) {
    if ($a->age === $b->age) return 0;
    return $a->age < $b->age ? -1 : 1;
});

// After: one expression
usort($users, fn($a, $b) => $a->age <=> $b->age);

Works on strings, integers, floats, and arrays. For multi-field sorting, chain comparisons with the || operator — when the first comparison is 0 (equal), fall through to the next:

// Sort by last name, then first name, then age
usort($people, fn($a, $b) =>
    $a->lastName  <=> $b->lastName  ?:
    $a->firstName <=> $b->firstName ?:
    $a->age       <=> $b->age
);

// Sort products: in-stock first, then by price ascending
usort($products, fn($a, $b) =>
    $b->inStock <=> $a->inStock ?: $a->price <=> $b->price
);

The spaceship also works with PHP's built-in comparison semantics, so '10' <=> '9' returns 1 (numeric string comparison) and [1, 2] <=> [1, 1] compares element-by-element.

Significance: Ergonomics

The usort comparator pattern is one of the most-written pieces of PHP boilerplate. The spaceship operator collapses it to a single expression, and the ?: chaining pattern for multi-key sorts reads almost like a specification.