In PHP, two objects are only === when they're the exact same instance, even if every property matches. This RFC from Rob Landers adds a data modifier for classes whose instances behave more like values, the way arrays do. Two data objects are equal when their properties are equal.
Show me
Here is a trimmed version of the RFC's example:
data class Rectangle { public function __construct(public int $width, public int $height) {} } $rectangle = new Rectangle(10, 20); $newRectangle = $rectangle; $newRectangle->width = 30; $otherRectangle = new Rectangle(30, 20); assert($rectangle !== $newRectangle); // true assert($newRectangle === $otherRectangle); // true
Changing $newRectangle didn't touch $rectangle, and two separate objects with the same values count as equal.
How it works
Data classes use copy-on-write, meaning PHP only makes a copy when you change something. Arrays already work this way: assigning one to a new variable is cheap, and the copy happens on the first write.
A few more rules:
- Constructors are the exception. Changes made inside the constructor don't trigger a copy.
- No dynamic properties. Every property must be declared.
- Other modifiers still work. You can write
final readonly data class Point. - Inheritance stays in the family. A data class can only extend another data class, and a parent and child with the same values are still not equal.
- Only
===and!==are defined. Other comparisons are left undefined. - Most class features still work, including interfaces, traits, hooks, serialization and anonymous classes.
Reflection gets a new isDataClass() method, and var_dump() shows data object(Point) for data objects. Cloning a data object works, but the result is a copy that's equal to the original.
What it means for existing code
data becomes a semi-reserved keyword, which means it has special meaning only in certain positions. That may break libraries that parse PHP code. Other language features are unaffected.
Two questions are still open: whether data objects can be used as array keys, and whether they can be used as default values for properties.
Where it stands
The RFC is under discussion and has sat at version 0.9 since November 2024. It targets the next PHP 8.x or 9.0 and would need a two-thirds vote. There's a pull request with the implementation, but no vote on the page yet.
We list it as inactive because the page hasn't changed since November 2024 and no vote was ever held.