PHP strict types, match, and the nullsafe operator

declare(strict_types=1) tells PHP not to convert argument types silently. With it, passing an int where a string is required is a TypeError instead of a hidden conversion. Union types such as int|string|null list the types a parameter accepts. The match expression compares with strict equality, returns a value, and throws if nothing matches, unlike switch.

PHP
<?php
declare(strict_types=1);

function describe(int|string|null $value): string
{
    return match (true) {
        $value === null => "nothing",
        is_int($value) && $value < 0 => "negative int",
        is_int($value) => "int $value",
        default => "string '$value'",
    };
}

echo describe(5), "\n", describe(-2), "\n", describe("hi"), "\n", describe(null), "\n";

class Address
{
    public function __construct(public ?string $city = null) {}
}

class User
{
    public function __construct(public string $name, public ?Address $address = null) {}
}

$users = [new User("Ada", new Address("London")), new User("Bo")];
foreach ($users as $user) {
    echo $user->name, ": ", $user->address?->city ?? "unknown", "\n";
}

try {
    echo strlen(123);
} catch (TypeError $e) {
    echo "TypeError caught\n";
}
Read the full lesson