A property hook that should have stayed a method

A get hook that looked like a property, read like a property, and issued a database query.

// what I wrote
public ?Invoice $invoice {
    get => $this->invoices->findForOrder($this->id);
}

// and the loop somebody wrote three weeks later
foreach ($orders as $order) {
    if ($order->invoice !== null) { /* ... */ }
}
// 200 queries, and nothing at the call site suggests it

The rule I wrote down in December — pure, cheap and total — was violated within a quarter by the person who wrote the rule. A hook makes work invisible, and invisible work in a loop is the oldest performance bug there is. It went back to invoice(), which is uglier and honest about being a call.