Embracing Union Types in PHP 8: An In-Depth Look at Their Benefits for Developers

Nemanja Milenkovic
4 min readApr 20, 2023

--

Introduction

With the introduction of PHP 8.0, union types have emerged as a valuable addition to the language’s type system. They enable developers to specify that a value can be one of multiple types, paving the way for more flexible code. In this article, we will dive deep into the benefits of union types in PHP 8 and how they impact developers, using examples to illustrate the concepts. This article is designed for developers who wish to understand and adopt the new type system in their PHP projects.

Improved Code Clarity and Readability

Union types enhance code readability by allowing developers to communicate their intent more effectively. With union types, it becomes clear which types are expected as input or output in functions, class methods, and properties.

For instance, suppose you have a function that accepts an integer or a string as an input parameter. Without union types, you would have to rely on comments or documentation to convey this information:

/**
* Concatenates the prefix and the input value.
*
* @param int|string $value
* @return string
*/
function addPrefix($value) {
return ‘prefix_’ . $value;
}

With union types, the code becomes more self-explanatory:

function addPrefix(int|string $value): string {
return ‘prefix_’ . $value;
}

The second example is easier to understand since the allowed types are clearly defined within the function signature.

Enhanced Type Safety

Union types help catch type-related issues early in the development process, reducing the likelihood of bugs slipping into production. By explicitly stating which types are allowed, you enforce strict type checking that prevents invalid values from being used.

Consider a simple example of a function that calculates the area of a circle:

function areaOfCircle($radius): float {
return pi() * $radius * $radius;
}

Without type hinting, there’s no guarantee that the input value will be a number. With union types, you can ensure the input is either an integer or a floating-point number:

function areaOfCircle(int|float $radius): float {
return pi() * $radius * $radius;
}

Easier Refactoring and Code Evolution

Union types promote backward compatibility by allowing you to handle multiple types in a function or class method. This flexibility enables you to modify your codebase without breaking existing functionality.

For example, consider a function that initially only accepts an array but is later extended to support Traversable objects:

function processData(array $data) {
// …
}

Instead of creating a new function or using type casting and checks to accept Traversable objects, you can simply update the type hint:

function processData(array|Traversable $data) {
// …
}

This change allows the function to support both array and Traversable objects without breaking existing code that relies on the original array type.

Better Autocompletion and Code Analysis

IDEs and code editors can utilize union types to improve autocompletion suggestions and code analysis. By providing more specific type information, the development environment is better equipped to understand the code and help prevent potential errors.

For instance, when using union types in a popular IDE like PhpStorm, the editor will suggest contextually appropriate methods and properties for the specified types. This assistance speeds up the development process and minimizes the risk of introducing errors.

Reduced Need for Type Casting and Type Checks

Union types eliminate the need for excessive type casting and type checks, resulting in cleaner and more concise code. By explicitly stating the accepted types, you no longer need to rely on functions like is_int() or is_string() to validate input data.

Consider a function that accepts a numeric value as a string or an integer, and returns its absolute value:

function absoluteValue($value) {
if (is_int($value)) {
return abs($value);
} elseif (is_string($value) && is_numeric($value)) {
return abs((int)$value);
}

throw new InvalidArgumentException(“Invalid input type”);
}

By using union types, you can simplify the function and remove the need for type checks:

function absoluteValue(int|string $value): int {
if (is_string($value) && is_numeric($value)) {
$value = (int)$value;
}

return abs($value);
}

The second example is not only more concise, but it also benefits from the added type safety provided by union types.

Conclusion

Union types, introduced in PHP 8, offer several advantages for developers. They improve code clarity and readability, enhance type safety, support easier refactoring and code evolution, provide better autocompletion and code analysis, and reduce the need for type casting and type checks. By embracing union types, developers can create cleaner, more maintainable, and safer PHP code.

Whether you’re a seasoned PHP developer or new to the language, adopting union types in your projects will help you harness the full potential of PHP 8’s improved type system. Keep exploring and experimenting with union types, and you’ll undoubtedly experience the benefits they bring to your code.

--

--

Nemanja Milenkovic

Web dev expert with 20+ yrs experience. LAMP technologies maestro, adept in PHP, Laravel, Symfony...