Laravel · Php

PHP 8 New Features — A Complete Guide

A tour of PHP 8.0 through 8.3's most impactful features — union types, match, nullsafe operator, constructor promotion, readonly properties, enums, fibers, named arguments — with real code for each.

John Kihiu12 min read

PHP spent years being the language people apologized for using. The 8.x line is where that stopped being fair. Union types, match expressions, constructor promotion, readonly properties, and native enums didn't arrive all at once, but taken together across 8.0 through 8.3 they changed what idiomatic PHP looks like — less defensive boilerplate, more of the type system actually enforcing what you meant. Here's the subset that changed how I write code day to day, not the full changelog.

Union types and the match expression

PHP 8.0 let you declare a parameter or return type as one of several types explicitly — int|string — instead of falling back to no type hint at all or a docblock comment nobody enforces. The same release added match, a stricter, expression-based alternative to switch: no fallthrough, strict (===) comparison instead of switch's loose comparison, and it returns a value directly.

PHP · UNION TYPES + MATCH
function formatId(int|string $id): string
{
    return match (true) {
        is_int($id)                => sprintf('#%06d', $id),
        str_starts_with($id, 'TX') => strtoupper($id),
        default                    => (string) $id,
    };
}

// match with no default and no matching arm throws UnhandledMatchError
// at the call site — a silent switch fallthrough becomes a loud failure

Constructor promotion and readonly properties

Constructor property promotion (8.0) collapses the property declaration, constructor parameter, and assignment into one line per property — the single biggest reduction in DTO/value-object boilerplate PHP has had. Readonly properties (8.1) make a promoted property immutable after construction, which is what actually makes the resulting object trustworthy as a value object rather than just terser.

PHP · PROMOTED + READONLY
final class Money
{
    public function __construct(
        public readonly int $amountMinor,
        public readonly string $currency,
    ) {}

    public function add(Money $other): self
    {
        if ($this->currency !== $other->currency) {
            throw new InvalidArgumentException('Currency mismatch.');
        }
        return new self($this->amountMinor + $other->amountMinor, $this->currency);
    }
}

// Before 8.0/8.1 this was ~15 lines: property declarations,
// constructor params, assignments, and no immutability guarantee at all.

The nullsafe operator

The nullsafe operator (?->, 8.0) short-circuits an entire chain to null the moment any link in it is null, replacing nested isset() or ?? checks that used to guard every step of a property/method chain.

PHP · NULLSAFE CHAINING
// Before: three isset checks or a chain of ?? null
$city = $order->customer !== null && $order->customer->address !== null
    ? $order->customer->address->city
    : null;

// After: one expression, short-circuits at the first null
$city = $order->customer?->address?->city;
Nullsafe stops the whole chain, not just one link

If $order->customer is null, the entire expression evaluates to null without calling ->address at all — it doesn't throw on the missing link and continue. That's usually what you want, but it also means a typo'd property earlier in the chain can silently produce null instead of surfacing an error, so it isn't a substitute for validating data you actually expect to be present.

Enums and Fibers (8.1)

Native enums replaced the class-constant-plus-validation pattern almost every PHP codebase had invented independently, and backed enums (string or int-backed) give you a real type at API and database boundaries instead of a bare scalar. Fibers, shipped the same release, are lower-level — a primitive for pausing and resuming execution with values passed in both directions — and they're the reason async libraries like Amphp and ReactPHP got meaningfully better ergonomics, even though most application code never touches a Fiber directly.

PHP · BACKED ENUM WITH A METHOD
enum OrderStatus: string
{
    case Pending = 'pending';
    case Paid    = 'paid';
    case Shipped = 'shipped';

    public function isTerminal(): bool
    {
        return $this === self::Shipped;
    }
}

Named arguments (8.0) and readonly classes (8.2/8.3)

Named arguments let you call a function by parameter name, skipping optional parameters out of order — the fix for functions with several boolean flags that used to be unreadable at the call site (render($data, true, false, true) becomes render($data, sortable: true, striped: true)). PHP 8.2 refined readonly to cover more cases cleanly, and 8.3 added the readonly class shorthand, marking every property of a class readonly without repeating the keyword on each one.

These compound with each other

The biggest quality-of-life jump isn't any single 8.x feature — it's combining them: a readonly class with promoted constructor properties, backed enums for its status fields, and named arguments at every call site. That combination is close to what a DTO looks like in languages with native record types, and PHP got there without a new syntax construct dedicated to records.

Wrapping up

None of these features individually is dramatic — that's arguably the point. Union types and match tightened the type system without new runtime behavior most code notices; constructor promotion and readonly properties killed a specific category of boilerplate and made immutability a first-class option instead of a discipline you enforced by convention; enums replaced a workaround every codebase had reinvented slightly differently. The cumulative effect across 8.0 to 8.3 is that idiomatic PHP in 2026 looks noticeably different, and stricter, than idiomatic PHP in 2019 — and almost none of it required a framework or a library to get.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.