What if your code could automatically guarantee objects have all the features you need, without messy checks?
Why Intersection types in PHP? - Purpose & Use Cases
Imagine you have a function that needs an object which is both a Logger and a Serializer. Without intersection types, you must manually check and combine these capabilities, making your code messy and hard to maintain.
Manually verifying that an object meets multiple interfaces means writing extra checks and error handling everywhere. This slows development and increases bugs because you might forget a check or mix up types.
Intersection types let you declare that a value must satisfy multiple types at once. This means the language enforces the object has all required features, making your code cleaner and safer.
$obj = getObject(); if (!($obj instanceof Logger) || !($obj instanceof Serializer)) { throw new Exception('Invalid object'); }
function process(Logger&Serializer $obj) {
// $obj is guaranteed to be both Logger and Serializer
}It enables writing precise and safe code that works only with objects having multiple required capabilities, reducing bugs and improving clarity.
When building a system that logs data and also converts it to JSON, intersection types ensure the object you pass can do both without extra checks.
Manual checks for multiple types are slow and error-prone.
Intersection types enforce multiple type requirements at once.
This leads to cleaner, safer, and more maintainable code.
Practice
function example(SomeType&OtherType $param) {}Solution
Step 1: Understand intersection type syntax
In PHP, the & symbol between types means the value must satisfy all listed types simultaneously.Step 2: Interpret the function parameter
The parameter typeSomeType&OtherTypemeans the argument must be both SomeType and OtherType at the same time.Final Answer:
A type that requires the value to satisfy both SomeType and OtherType. -> Option AQuick Check:
Intersection type = must satisfy all types [OK]
- Confusing & with | (union type)
- Thinking it creates a new combined class
- Assuming it accepts either type instead of both
Solution
Step 1: Recall intersection type syntax
PHP uses a single ampersand & to declare intersection types between multiple types.Step 2: Check each option
function test(A & B $param) {} uses & correctly. function test(A | B $param) {} uses | which is union type. function test(A, B $param) {} uses comma which is invalid. function test(A && B $param) {} uses && which is not valid syntax.Final Answer:
function test(A & B $param) {} -> Option AQuick Check:
Intersection type uses & symbol [OK]
- Using | instead of &
- Using commas to separate types
- Using && instead of &
interface A { public function foo(): string; }
interface B { public function bar(): string; }
class C implements A, B {
public function foo(): string { return 'foo'; }
public function bar(): string { return 'bar'; }
}
function test(A & B $obj) {
echo $obj->foo() . ' ' . $obj->bar();
}
$c = new C();
test($c);Solution
Step 1: Understand class and interfaces
Class C implements both interfaces A and B, so it has methods foo() and bar().Step 2: Analyze function test parameter and call
The function test requires an argument that satisfies both A and B (intersection type). Object $c satisfies both. The function echoes foo() and bar() results concatenated with a space.Final Answer:
foo bar -> Option DQuick Check:
Object satisfies both interfaces, prints both methods [OK]
- Expecting only one method output
- Thinking it causes a TypeError
- Confusing intersection with union types
interface X { public function x(): void; }
interface Y { public function y(): void; }
class Z implements X {
public function x(): void {}
}
function foo(X & Y $param) {
$param->x();
$param->y();
}
$z = new Z();
foo($z);Solution
Step 1: Check class Z implementation
Class Z implements only interface X, not Y, so it does not satisfy the intersection type X & Y.Step 2: Analyze function call with $z
Function foo requires a parameter that implements both X and Y. Passing $z causes a TypeError because $z lacks Y.Final Answer:
Class Z does not implement interface Y, so it cannot satisfy X & Y. -> Option CQuick Check:
Intersection requires all interfaces implemented [OK]
- Assuming partial interface implementation is enough
- Thinking syntax is wrong instead of logic
- Ignoring missing methods from interfaces
interface Logger { public function log(string $msg): void; }
interface FileWriter { public function write(string $data): void; }
class FileLogger implements Logger, FileWriter {
public function log(string $msg): void { echo "Log: $msg\n"; }
public function write(string $data): void { echo "Write: $data\n"; }
}
function process(Logger & FileWriter $obj, string $message) {
$obj->log($message);
$obj->write($message);
}
$fl = new FileLogger();
process($fl, "Hello World");What will be the output and why is intersection type useful here?
Solution
Step 1: Understand class and interfaces
FileLogger implements both Logger and FileWriter, so it has both log() and write() methods.Step 2: Analyze function process behavior
The function requires an object that satisfies both Logger and FileWriter (intersection type). It calls both log() and write() methods on the object.Step 3: Predict output
Calling process with $fl outputs:
Log: Hello World
Write: Hello WorldFinal Answer:
Output:
Log: Hello World
Write: Hello World
Intersection ensures $obj has both log() and write() methods. -> Option BQuick Check:
Intersection type ensures all required methods exist [OK]
- Thinking only one interface method is called
- Believing intersection types cause runtime errors
- Ignoring that both methods are called
Ready to prove it?
Pass the test and this pattern moves unknown
