Re: [RFC] Readonly Variables
| From: | Joshua Rüsweg | Date: | Tue, 24 Feb 2026 18:52:11 +0000 |
| Subject: | Re: [RFC] Readonly Variables | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-130154@lists.php.net to get a copy of this message | ||
Hello Kamil,
> On 23. Feb 2026, at 22:58, Kamil Tekiela <tekiela246@gmail.com> wrote:
>
> 1. Why the use of readonly keyword? Why not const or some new keyword,
> e.g. locked.
I spent a long time thinking about the right keyword. In an early stage of development I chose
const, as it is already used in this way in JavaScript, for example. However, the
further I developed the feature and the more feedback I gathered from others, the more I gravitated
towards readonly. The readonly keyword is already used in PHP for class
properties and serves exactly the same purpose: declaring variables as immutable. Reusing
readonly for variables is therefore consistent with existing PHP semantics. The
const keyword, on the other hand, has fundamentally different semantics in PHP. A
const declaration at the top level defines a globally accessible constant, and inside a
class it defines a class constant. This is quite different from a locally scoped immutable variable,
and using const for this feature would likely cause confusion for PHP developers who are already
familiar with its existing meaning. Introducing an entirely new keyword for this purpose, such as
locked, would in my opinion be counterproductive, as it could be unintuitive for
developers who are already familiar with readonly and its meaning in PHP.
> 2. Why does unset not remove the variable completely? If you want a
> feature to only unlock the variable then it probably needs a new
> keyword, e.g. unlock
Thank you for pointing that out, as I apparently expressed myself ambiguously in the RFC.
unset() behaves exactly as it does for regular variables: it removes the variable
entirely. The only additional effect is that the readonly flag is cleared along with
it, meaning the variable name can subsequently be reused with a new assignment, without the
readonly flag. I have updated the RFC to make this behavior more explicit.
Regarding the idea of a dedicated unlock mechanism: I don't think this is necessary, and I
honestly don't see a practical use case for it. If a variable needs to be modified after its
initial assignment, it simply should not be declared as readonly in the first place.
> 3. What exactly does this mean: "Readonly variables inside loops are
> permitted but limited to a single declaration"? What does a single
> declaration look like?
A readonly variable declared inside a loop is exposed to the outer scope, just like any other
variable in PHP. This means that on the second iteration, PHP would attempt to re-assign an already
initialized readonly variable, which results in a fatal error. A "single declaration"
therefore means that the readonly variable can only be initialized once throughout the entire
execution of the loop, not once per iteration.
I hope this clarifies the behavior. Please let me know if you have any further questions.
> 4. How will this impact optimizer and JIT?
Thank you for raising this point. I have not yet investigated the impact on the optimizer and JIT,
as the current implementation is an initial proof of concept intended to gather feedback from the
community. I will definitely look into this before the voting phase and investigate whether and how
readonly variables can be leveraged for potential optimizations. I will report back with my
findings.
> 5. You said that readonly variables cannot be used with the global
> keyword. But what about readonly variables in global scope? Will they
> still behave like a typical global variable?
I am not entirely sure what you mean by "typical global variable behavior", so I will try
to address what I believe you are asking.
If your question is whether a readonly variable declared in the global scope can be imported into a
function via the global statement, the answer is no. Importing a readonly variable via
global is forbidden and results in an error.
If you are asking whether readonly variables declared in the global scope are automatically
accessible in function scopes, the answer is also no. Readonly variables follow the same scoping
rules as regular variables, meaning they are not automatically available inside functions, just as
regular variables are not.
If you meant something else entirely, please feel free to clarify and I will be happy to address it.
> 6. What exactly counts as a variable declaration? When is it a valid
> syntax to use this keyword? I don't think PHP had the concept of
> variable declaration until now.
By "declaration" I simply mean a regular variable assignment prefixed with the readonly
keyword:
```
<?php
readonly $foo = "bar”;
```
You are right that PHP has not had a formal concept of variable declaration until now. The readonly
keyword in this context is purely a modifier on a standard assignment statement, signaling that the
variable cannot be re-assigned after its initial value has been set. Any valid assignment expression
can be used as the initial value, including object instantiation, function calls, or scalar values.
> 7. What about compound variables such as arrays and objects?
The behavior differs depending on the type of value assigned to a readonly variable.
For arrays, the entire array is immutable. This means that neither the array itself nor its elements
can be modified after the initial assignment:
```
<?php
readonly $arr = [1, 2, 3];
$arr[] = 4; // Error: Cannot re-assign readonly variable
$arr[0] = 99; // Error: Cannot re-assign readonly variable
```
For objects, the behavior is consistent with how readonly works for class properties: the variable
binding is immutable, meaning the object reference cannot be replaced with a different object.
However, the internal state of the object itself can still be modified:
```
<?php
readonly $obj = new stdClass();
$obj->value = "changed"; // Valid: modifying the object's internal state is
allowed
$obj = new stdClass(); // Error: Cannot re-assign readonly variable
```
I have added examples for both cases to the RFC to make this behavior explicit.
> I would prefer starting with readonly parameters as I feel that would
> bring the most value.
I find the idea of readonly parameters interesting and have already given it some thought. However,
it is out of scope for this RFC, as I wanted to keep the initial proposal focused and manageable. I
have already mentioned it in the Future Scope section of the RFC as a potential natural extension
that could be addressed in a separate RFC in the future.
> I think it would also be worthwhile to investigate a simpler syntax
> for define().
It is worth noting that PHP already provides two ways to define global constants:
define() and the const keyword. Both serve a different purpose than
readonly variables, as they are globally accessible and not scoped to a local or functional context.
See: https://3v4l.org/1r6gk
Cheers,
Joshua Rüsweg