haphpiness

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

Multi-Catch — One Block, Many Exception Types

Two exception types, one recovery strategy, and no shared parent class. Before PHP 7.1 that meant copying the handler, or catching something far too broad and hoping.

// Before: the same three lines, twice.
try {
    $result = $client->send($request);
} catch (NetworkException $e) {
    $this->logger->warning('retrying', ['error' => $e->getMessage()]);
    return $this->retry($request);
} catch (TimeoutException $e) {
    $this->logger->warning('retrying', ['error' => $e->getMessage()]);
    return $this->retry($request);
}
// After: one block, both types, and $e is typed as the union.
try {
    $result = $client->send($request);
} catch (NetworkException | TimeoutException $e) {
    $this->logger->warning('retrying', ['error' => $e->getMessage()]);
    return $this->retry($request);
}

The alternative people actually reached for was catch (Exception $e), which quietly swallows the LogicException from your own broken code alongside the network blip you meant to handle. Multi-catch removed the incentive to be sloppy: naming both types is now shorter than being vague.

PHP 8.0 finished the thought by making the variable optional, for when the type is the information.

try {
    $config = $this->loadConfig();
} catch (FileNotFound | ParseError) {
    // We know what happened. We don't need the object.
    $config = Config::defaults();
}

Significance: Precision Over Convenience

Every language ends up teaching its users habits through friction. When catching two specific exceptions cost twice the code of catching all of them, codebases filled with catch (Exception $e) and real bugs disappeared into recovery paths meant for transient failures. Multi-catch made the precise thing the convenient thing, which is the only reliable way to change how people write code.