0
0
PHPprogramming~15 mins

Union types in practice in PHP - Deep Dive

Choose your learning style9 modes available
Overview - Union types in practice
What is it?
Union types in PHP allow a variable, parameter, or return value to accept or return multiple different types. Instead of restricting a value to just one type, union types let you specify a list of possible types separated by a vertical bar (|). This helps make code more flexible while still keeping type safety. It was introduced to make functions and methods more expressive about what kinds of values they can handle.
Why it matters
Without union types, developers had to rely on loose typing or complex checks inside functions, which could lead to bugs and unclear code. Union types solve this by letting the code explicitly say: 'I accept this OR that type.' This clarity helps catch errors early and makes code easier to understand and maintain. It also improves collaboration because everyone knows exactly what types are expected.
Where it fits
Before learning union types, you should understand basic PHP types and type declarations. After mastering union types, you can explore advanced typing features like intersection types, nullable types, and generics in PHP. Union types build on the foundation of type declarations and lead to writing safer, clearer code.
Mental Model
Core Idea
Union types let a value be one of several specified types, making code flexible yet type-safe.
Think of it like...
Imagine a key that can open multiple doors, but only those specific doors. Union types are like that key, allowing a variable to 'open' or accept several specific types, but nothing outside that set.
┌───────────────┐
│   Variable    │
│   accepts     │
│ ┌───────────┐ │
│ │ Type A    │ │
│ ├───────────┤ │
│ │ Type B    │ │
│ ├───────────┤ │
│ │ Type C    │ │
│ └───────────┘ │
└───────────────┘

Meaning: Variable can be Type A OR Type B OR Type C
Build-Up - 6 Steps
1
FoundationBasic type declarations in PHP
🤔
Concept: Learn how PHP enforces types on function parameters and return values.
Result
Hello, Alice!
Understanding simple type declarations is essential because union types extend this idea by allowing multiple types instead of just one.
2
FoundationWhat are union types in PHP?
🤔
Concept: Union types allow specifying multiple types separated by | for parameters or return types.
Result
20HI
Union types let functions accept or return more than one type, making them more flexible and expressive.
3
IntermediateUsing union types with class types
🤔
Concept: Union types can include classes, interfaces, and built-in types together.
bark(); } return $animal->meow(); } $dog = new Dog(); $cat = new Cat(); echo animalSound($dog); // Woof! echo animalSound($cat); // Meow!
Result
Woof!Meow!
Union types work seamlessly with objects, allowing a function to accept different classes and handle them safely.
4
IntermediateNullable types vs union types
🤔Before reading on: Do you think nullable types are a special case of union types or something different? Commit to your answer.
Concept: Nullable types are a shorthand for a union with null, but union types are more general.
Result
No name provided.Name: Bob
Knowing nullable types are just a special case of union types helps unify your understanding of PHP's type system.
5
AdvancedUnion types with mixed and type checks
🤔Before reading on: Will PHP allow 'mixed' combined with other types in a union? Commit to yes or no.
Concept: The 'mixed' type means any type, so combining it with others in a union is redundant and disallowed. Also, runtime type checks are needed to handle union types safely.
Result
Integer: 5String: testOther type
Understanding PHP's rules about 'mixed' prevents invalid type declarations and knowing to check types at runtime avoids errors.
6
ExpertUnion types and backward compatibility challenges
🤔Before reading on: Do you think adding union types to existing code can break older PHP versions or cause subtle bugs? Commit to your answer.
Concept: Union types require PHP 8.0+, so using them in code that runs on older versions causes syntax errors. Also, union types can expose hidden bugs if legacy code assumes a single type.
/* Legacy function: function calculate($value) { return $value * 2; } Adding union type: function calculate(int|float $value): int|float { return $value * 2; } If old code passed strings, it now breaks or behaves differently. */
Result
Code with union types fails on PHP < 8.0 and may reveal type assumptions in legacy code.
Knowing the version and legacy impact of union types helps avoid runtime errors and subtle bugs during upgrades.
Under the Hood
At runtime, PHP checks the actual type of a value against the declared union types. When a function is called, PHP verifies if the argument matches any of the allowed types in the union. If not, it throws a TypeError. Internally, the engine stores the union type as a set of allowed types and performs fast type comparisons. This mechanism ensures type safety without sacrificing flexibility.
Why designed this way?
PHP was originally loosely typed, but as applications grew complex, strict typing became necessary to reduce bugs. Union types were introduced to balance strictness with flexibility, allowing multiple valid types without losing error checking. The design avoids complicating the type system with too many special cases and keeps runtime checks efficient.
┌───────────────┐
│ Function Call │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Check Argument│
│ Type Matches? │
└──────┬────────┘
   Yes │ No
       ▼    ┌───────────────┐
       │    │ Throw TypeError│
       ▼    └───────────────┘
┌───────────────┐
│ Execute Body  │
└───────────────┘
Myth Busters - 3 Common Misconceptions
Quick: Does a union type mean the variable can hold multiple types at the same time? Commit to yes or no.
Common Belief:A union type means a variable can hold multiple types simultaneously, like a list of types all at once.
Tap to reveal reality
Reality:A union type means the variable can hold one type at a time, but that type can be any one of the specified types, never multiple simultaneously.
Why it matters:Believing a variable can hold multiple types at once leads to confusion and incorrect assumptions about how data is stored and used.
Quick: Can you combine 'mixed' with other types in a union? Commit to yes or no.
Common Belief:You can combine 'mixed' with other types in a union to be extra flexible.
Tap to reveal reality
Reality:'mixed' already means any type, so combining it with others in a union is invalid and causes syntax errors.
Why it matters:Trying to combine 'mixed' with other types wastes effort and causes code that won't run, blocking progress.
Quick: Does adding union types always improve code safety without any drawbacks? Commit to yes or no.
Common Belief:Using union types always makes code safer and better with no downsides.
Tap to reveal reality
Reality:While union types improve clarity, they can introduce complexity and require careful runtime checks. Also, they can break compatibility with older PHP versions.
Why it matters:Ignoring these tradeoffs can cause unexpected bugs and deployment issues.
Expert Zone
1
Union types do not support 'void' or 'callable' combined with other types, which can surprise developers.
2
When multiple union types are nested or combined with nullable types, the order and grouping affect readability but not behavior.
3
Static analysis tools can infer union types even if not declared, but explicit union types improve documentation and error detection.
When NOT to use
Avoid union types in codebases that must support PHP versions below 8.0 or where strict single-type contracts are required. Instead, use polymorphism or separate functions for different types.
Production Patterns
In production, union types are often used in APIs to accept multiple input formats, in value objects that can represent different states, and in libraries to provide flexible but safe interfaces. They are combined with runtime type checks and thorough testing to ensure robustness.
Connections
TypeScript union types
Similar pattern in a different language
Understanding PHP union types helps grasp TypeScript's union types, which also allow variables to hold multiple possible types, improving cross-language type safety.
Set theory in mathematics
Union types correspond to set unions
Union types are like the union of sets, where a value belongs to any one of the sets (types), helping understand the concept through a mathematical lens.
Biology species classification
Categorizing organisms into multiple possible groups
Just as an organism can belong to multiple categories (e.g., genus or family), union types let a variable belong to multiple type categories, showing how classification concepts apply across fields.
Common Pitfalls
#1Declaring a union type with 'mixed' combined with other types.
Wrong approach:function foo(mixed|int $x) {}
Correct approach:function foo(mixed $x) {}
Root cause:Misunderstanding that 'mixed' already includes all types, so combining it with others is redundant and invalid.
#2Assuming a variable with a union type can hold multiple types simultaneously.
Wrong approach:$value = 5; $value = "hello"; // expecting both types stored at once
Correct approach:$value = 5; // holds int $value = "hello"; // now holds string, replacing previous value
Root cause:Confusing union types with collections or arrays that hold multiple values at once.
#3Using union types in code that must run on PHP versions below 8.0.
Wrong approach:function test(int|string $x) { return $x; } // syntax error on PHP 7
Correct approach:function test($x) { /* manual type checks */ return $x; }
Root cause:Not knowing union types require PHP 8.0 or newer, leading to syntax errors on older versions.
Key Takeaways
Union types let PHP variables, parameters, and return values accept multiple specified types, improving flexibility and safety.
They are written using the vertical bar (|) to separate allowed types and require PHP 8.0 or newer.
Union types are not multiple types at once, but one type from a set of allowed types at any time.
Nullable types are a special case of union types that include null as one option.
Using union types requires careful runtime checks and awareness of compatibility to avoid bugs.