PHP has const and define() for values that never change, but there's no way to lock a local variable inside a function. This RFC from Joshua Rüsweg adds a readonly modifier for variables, so once you assign one, you can't assign it again. It works like JavaScript's const and Swift's let.
How it works
readonly $connection = new PDO($dsn, $user, $password); $connection = null; // Error: Cannot re-assign readonly variable
You can declare more than one at a time:
readonly $foo = "bar", $bar = "baz";
The RFC sets out these rules:
- Normal scope. A readonly variable lives in its function, method or closure, like any other variable.
- Arrays are fully locked. You can't add to or modify a readonly array.
- Objects aren't. You can't swap in a new object, but you can still change its properties, which matches how
readonlyworks on class properties. - No workarounds. Compound operators like
+=and++, references, pass-by-reference,global,extract()and variable variables ($$name) can't change it either. unset()clears it. After you unset one, you can reuse the name.- Only if it ran. If the
readonlyline sits inside anifblock that never runs, the variable stays free to assign. - Once per loop. A readonly declaration inside a loop fails on the second iteration.
- No
staticmix. A variable can't be bothreadonlyandstatic. - No destructuring.
readonly [$a, $b] = [1, 2];is a parse error for now.
readonly $obj = new stdClass(); $obj->value = "hello"; // Valid $obj = new stdClass(); // Error: Cannot re-assign readonly variable
What it means for existing code
Nothing breaks. Putting readonly in front of a variable is a parse error today, so no working code uses it. IDEs and static analysis tools like PHPStan and Psalm would need updates for the new syntax, but after that they could know for sure that a variable never changes instead of relying on @readonly docblocks.
Where it stands
The RFC is under discussion on the internals mailing list. It's at version 0.1, first published on February 22, 2026, and targets the next PHP 8.x release. It needs a two-thirds majority to pass, and no vote has happened yet.