haphpiness

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

Constants in Traits

Traits could hold properties and methods but not constants, which is a strange gap once you notice it. A trait that encodes behavior around a fixed value had to keep the value somewhere else, and trust every consuming class to define it.

// Before 8.2: the trait needs a constant it cannot declare.
trait Retryable {
    public function attempts(): int {
        return static::MAX_ATTEMPTS;   // hope the class defined this
    }
}

class Job {
    use Retryable;
    // Forget this line and you get an Error at runtime, not at compile time.
    public const MAX_ATTEMPTS = 3;
}
// 8.2: the trait carries its own constant, and its own default.
trait Retryable {
    public const MAX_ATTEMPTS = 3;

    public function attempts(): int {
        return static::MAX_ATTEMPTS;
    }
}

class Job {
    use Retryable;                     // gets MAX_ATTEMPTS = 3
}

class StubbornJob {
    use Retryable;
    public const MAX_ATTEMPTS = 10;    // override when you mean to
}

It is a small feature and it closes a real hole. A trait is supposed to be a unit of reuse you can drop into a class and have work. Requiring the consumer to remember an undocumented constant made that a lie, and the failure showed up at runtime in whichever code path happened to call the method.

Significance: Consistency Wins

Most of PHP's recent history is filling in squares of a grid. Classes have constants, interfaces have constants, enums have constants, and traits did not, for no reason a user could explain. Every gap like this is a rule someone has to memorize. Closing them means the language behaves the way you would guess, which is worth more than any single feature.