Skip to main content

Command Palette

Search for a command to run...

Union Types in PHP 8: A Comprehensive Guide

Published
4 min readView as Markdown

PHP 8 introduced Union Types, a powerful feature that enhances type safety and flexibility in your applications. Union types allow developers to specify multiple types for a function's arguments, return values, or properties. This feature reduces ambiguity and reliance on PHPDoc annotations, paving the way for cleaner, more robust code.


What Are Union Types?

A union type lets you declare that a parameter, property, or return value can accept values of more than one type. Instead of using vague or mixed types, union types provide clarity about what kinds of data a function can handle.

Syntax

Union types are declared using the | (pipe) symbol between type names.

function calculate(int|float $number): int|float {
    return $number * 2;
}

In the example above:

  • The $number parameter accepts either an int or a float.
  • The return value of the function can also be either an int or a float.

How Union Types Work

Union types are particularly useful in scenarios where a function or method can logically accept multiple types of input or produce multiple types of output.

Examples

1. Function Arguments

function displayValue(int|string $value): void {
    echo "The value is: $value";
}

displayValue(42);       // Output: The value is: 42
displayValue("Hello");  // Output: The value is: Hello

Here, the displayValue function accepts both integers and strings, making it versatile for different data inputs.

2. Return Types

function findItem(int|string $id): string|bool {
    if (is_int($id)) {
        return "Found item with ID $id";
    } elseif (is_string($id)) {
        return "Found item with name $id";
    }
    return false;
}

echo findItem(10);      // Output: Found item with ID 10
echo findItem("itemX"); // Output: Found item with name itemX

This function demonstrates how union return types can handle varied return scenarios.

3. Class Properties

class Product {
    public int|float $price;

    public function __construct(int|float $price) {
        $this->price = $price;
    }
}

$product = new Product(19.99);
echo $product->price; // Output: 19.99

Class properties with union types make it easier to manage dynamic data structures.


Key Benefits of Union Types

  1. Improved Type Safety
    By explicitly specifying acceptable types, you reduce runtime errors and make your code safer.

  2. Enhanced Readability
    Union types make it clear what kind of data a function, method, or property expects, improving readability for other developers.

  3. Eliminates PHPDoc Overhead
    Previously, developers used PHPDoc to document mixed or multiple types. With union types, this information is now part of the actual code:

    // Before PHP 8
    /**
     * @param int|string $value
     * @return bool|string
     */
    function process($value) { ... }
    
    // PHP 8 with Union Types
    function process(int|string $value): bool|string { ... }
    
  4. Simplified Maintenance
    Union types reduce the need for extra type checks in code, making maintenance easier.


Union Type Limitations

While union types are a significant improvement, there are some limitations:

  1. Void Cannot Be Used in Unions
    The void type cannot be combined with other types since void signifies that no value is returned.

    // Invalid
    function test(): int|void { ... }
    
  2. Nullable Types Union types don’t replace nullable types. Use ? or explicitly include null in the union:

    function getValue(int|null $value): int|null { ... }
    
  3. Mixed Types
    The mixed type is a catch-all type in PHP and cannot be combined with union types, as mixed already includes all types.


Real-World Use Cases

  1. Flexible APIs
    APIs that handle multiple input types (e.g., strings or arrays) benefit significantly from union types:

    function search(string|array $query): array { ... }
    
  2. Dynamic Calculations
    Calculations involving numbers or data with varied types:

    function add(int|float $a, int|float $b): int|float {
        return $a + $b;
    }
    
  3. Custom Data Validation
    Union types simplify validation in frameworks or custom libraries:

    function validateInput(int|string $input): bool {
        return is_int($input) || is_string($input);
    }
    

Conclusion

Union types in PHP 8 are a welcome addition, offering better type safety, improved readability, and reduced reliance on PHPDoc annotations. By embracing this feature, developers can create cleaner, more robust, and maintainable code. Whether you’re building APIs, handling dynamic data, or improving type declarations, union types are a powerful tool to add to your arsenal.

More from this blog

Khang Nguyen

119 posts