Union Types and Intersection Types
PHP's type system took a giant leap in 8.0 with union types, and again in 8.1 with intersection types. You can now express exactly what a function accepts or returns — no more docblock-only type hints.
// Union types (PHP 8.0): accept multiple types
function processInput(int|string $input): string|false {
return is_int($input) ? str_pad((string)$input, 5, '0', STR_PAD_LEFT) : $input;
}
// Intersection types (PHP 8.1): require multiple interfaces
function saveEntity(Countable&Iterator $collection): void {
foreach ($collection as $item) {
// We know it's both Countable AND Iterator
}
}
// DNF types (PHP 8.2): combine both
function process((Countable&Iterator)|null $items): void {
// Nullable intersection type — the full expression
}
The type system went from "basically untyped" to one of the most expressive among dynamic languages. Static analyzers like PHPStan and Psalm can now catch entire categories of bugs at analysis time rather than runtime.
Significance: Type Safety
A strong type system doesn't just catch bugs — it makes refactoring safe, enables IDE autocompletion, and serves as living documentation. PHP's gradual typing lets you adopt types incrementally without rewriting your entire codebase.