Hi internals,
I opened PR #20903 https://github.com/php/php-src/pull/20903 to address
GH-10497 https://github.com/php/php-src/issues/10497 by allowing writes
to properties of objects referenced by consts (const binding stays
immutable, referenced objects can be mutable).
class C { public int $x = 0; } const OBJ = new C(); OBJ->x = 1;
// currently rejected, PR makes it valid var_dump(OBJ->x); // 1
Notes:
This is a language/semantics change and may overlap with / impact
GH-13800 https://github.com/php/php-src/pull/13800.
A potentially surprising case: some newly-valid writes can be a no-op
when they target a temporary const value, e.g.
- const X = [1,2,3]; X[] = 4;
- const Y = ['a' => 1]; Y['b'] = 2;
These become valid syntax but have no effect because the write happens on a
temporary basis.
Feedback on semantics + expected behavior for the temporary-write case is
appreciated.
Thanks,
__
Khaled Alam
Hi
A potentially surprising case: some newly-valid writes can be a no-op when they target a temporary const value, e.g. - const X = [1,2,3]; X[] = 4; - const Y = ['a' => 1]; Y['b'] = 2;These become valid syntax but have no effect because the write happens on a
temporary basis.Feedback on semantics + expected behavior for the temporary-write case is
appreciated.
This is too unexpected / error-prone for me. Trying to write into arrays
should remain disallowed / an Error, since this is never (?) useful.
For objects, I don't have a strong opinion, but I expect objects in
constants to be so rare that it probably isn't worth it to make a change
at all.
Best regards
Tim Düsterhus
Hi Tim
A potentially surprising case: some newly-valid writes can be a no-op when they target a temporary const value, e.g. - const X = [1,2,3]; X[] = 4; - const Y = ['a' => 1]; Y['b'] = 2;These become valid syntax but have no effect because the write happens on a
temporary basis.Feedback on semantics + expected behavior for the temporary-write case is
appreciated.This is too unexpected / error-prone for me. Trying to write into arrays
should remain disallowed / an Error, since this is never (?) useful.
No strong opinions on my part, but I'd like to point out that similar
situations already exist.
https://3v4l.org/ARMMS#v8.4.14
const C = [1, 2, 3];
function foo(): array {
return C;
}
foo()[] = 4;
var_dump(C);
PHP will happily duplicate the array returned from foo() to append 4,
without warning. The original array in C remains unmodified. It might
make sense for ASSIGN_DIM to warn/throw if OP1 is not a "pointer"
(indirect, reference or object), as then the operation will never have
an effect. But it seems to me this is a distinct issue.
Ilija
Hi
Am 2026-01-22 00:33, schrieb Ilija Tovilo:
No strong opinions on my part, but I'd like to point out that similar
situations already exist.https://3v4l.org/ARMMS#v8.4.14
const C = [1, 2, 3]; function foo(): array { return C; } foo()[] = 4; var_dump(C);PHP will happily duplicate the array returned from foo() to append 4,
without warning. The original array in C remains unmodified. It might
I'm aware. However to me this situation is a little different,
intuition-wise: A return value already looks and feels like a temporary
value to me (unless a by-ref return is used, of course, but those are
rare). An access on a const does not.
make sense for ASSIGN_DIM to warn/throw if OP1 is not a "pointer"
(indirect, reference or object), as then the operation will never have
an effect. But it seems to me this is a distinct issue.
That makes sense to me and IMO is a necessary precursor for this.
Best regards
Tim Düsterhus
Hi internals,
I'd like to bring attention back to this RFC, which has been updated to
v0.2 based on prior feedback:
https://wiki.php.net/rfc/const_object_property_write
Summary: This RFC proposes allowing property write operations (->) on
objects referenced by constants. Currently,
CONST_OBJ->prop = value produces "Cannot use temporary expression in write
context", even though the operation
mutates the object, not the constant binding.
What changed since the initial discussion (Jan 2026):
- Addressed Tim Düsterhus's and Ilija Tovilo's feedback regarding array
constant dim writes. The RFC now explicitly
scopes out dim/array writes and documents the "silent no-op" concern in a
dedicated section. A future RFC can
address whether ASSIGN_DIM on non-pointer OP1 should warn/throw — this is
acknowledged as a valid but distinct
issue. - Added by-reference passing support (BP_VAR_FUNC_ARG path), with tests.
- Added guardrail tests confirming that dim writes on constants, dim writes
on constant objects, and constant
rebinding all remain unchanged. - Updated the gh12102_3.phpt test: passing an array constant element by-ref
now correctly throws an Error instead of
silently operating on a temporary copy.
PR: https://github.com/php/php-src/pull/20903
I'd appreciate any feedback before moving this to a formal vote.
Best regards,
__
Khaled Alam
Hi
Am 2026-01-22 00:33, schrieb Ilija Tovilo:
No strong opinions on my part, but I'd like to point out that similar
situations already exist.https://3v4l.org/ARMMS#v8.4.14
const C = [1, 2, 3]; function foo(): array { return C; } foo()[] = 4; var_dump(C);PHP will happily duplicate the array returned from foo() to append 4,
without warning. The original array in C remains unmodified. It mightI'm aware. However to me this situation is a little different,
intuition-wise: A return value already looks and feels like a temporary
value to me (unless a by-ref return is used, of course, but those are
rare). An access on a const does not.make sense for ASSIGN_DIM to warn/throw if OP1 is not a "pointer"
(indirect, reference or object), as then the operation will never have
an effect. But it seems to me this is a distinct issue.That makes sense to me and IMO is a necessary precursor for this.
Best regards
Tim Düsterhus
Hi
Am 2026-04-04 02:52, schrieb Khaled Alam:
I'd like to bring attention back to this RFC, which has been updated to
v0.2 based on prior feedback:
Thank you. The updated RFC makes sense to me and with the removal of the
FOO[123] = 'bar'; support I don't have any further technical concerns.
With regard to the RFC policy, I just added the necessary “Abstain”
option to the vote.
I'm also noting some rendering issues in the RFC, particularly in the
Proposal section, where the “bullet point list” does not render
properly, due to the line-breaks in the markup. I'm also seeing that you
try to use the markdown syntax for inline code. That doesn't work in the
Wiki, since it doesn't speak markdown. When showcasing PHP code, I
recommend using <php>isset()</php> tags (<php> XML tag). For
non-PHP-Code ''BP_VAR_FUNC_ARG'' (two single-quotes works). You might
want to clean-up both of these, it will make the RFC look much nicer and
more approachable.
Please note that your RFC update is considered a major change, so it
needs 14 days of “cooldown” for discussion, before the RFC can go to
vote.
Best regards
Tim Düsterhus
Hi Tim,
With regard to the RFC policy, I just added the necessary “Abstain”
option to the vote.I'm also noting some rendering issues in the RFC, particularly in the
Proposal section, where the “bullet point list” does not render
properly, due to the line-breaks in the markup. I'm also seeing that you
try to use the markdown syntax for inline code. That doesn't work in the
Wiki, since it doesn't speak markdown. When showcasing PHP code, I
recommend using <php>isset()</php> tags (<php> XML tag). For
non-PHP-Code ''BP_VAR_FUNC_ARG'' (two single-quotes works). You might
want to clean-up both of these, it will make the RFC look much nicer and
more approachable.Please note that your RFC update is considered a major change, so it
needs 14 days of “cooldown” for discussion, before the RFC can go to
vote.
Thanks for the feedback, I just fixed the RFC
https://wiki.php.net/rfc/const_object_property_write rendering issues.
Best regards,
__
Khaled Alam
Hi
Am 2026-04-04 02:52, schrieb Khaled Alam:
I'd like to bring attention back to this RFC, which has been updated to
v0.2 based on prior feedback:Thank you. The updated RFC makes sense to me and with the removal of the
FOO[123] = 'bar';support I don't have any further technical concerns.With regard to the RFC policy, I just added the necessary “Abstain”
option to the vote.I'm also noting some rendering issues in the RFC, particularly in the
Proposal section, where the “bullet point list” does not render
properly, due to the line-breaks in the markup. I'm also seeing that you
try to use the markdown syntax for inline code. That doesn't work in the
Wiki, since it doesn't speak markdown. When showcasing PHP code, I
recommend using <php>isset()</php> tags (<php> XML tag). For
non-PHP-Code ''BP_VAR_FUNC_ARG'' (two single-quotes works). You might
want to clean-up both of these, it will make the RFC look much nicer and
more approachable.Please note that your RFC update is considered a major change, so it
needs 14 days of “cooldown” for discussion, before the RFC can go to
vote.Best regards
Tim Düsterhus
Hi all,
Reviving this thread. The v0.2 RFC
https://wiki.php.net/rfc/const_object_property_write (object property
writes on constants only;
array/dim writes removed) addressed Tim's concerns, and the 14-day cooldown
has long passed.
Unless there are further objections, I intend to open voting on Monday, 29
June 2026. 2/3 majority,
targets PHP 8.6, two-week vote.
RFC: https://wiki.php.net/rfc/const_object_property_write
PR: https://github.com/php/php-src/pull/20903
Best regards,
__
Khaled Alam
On Sat, Apr 11, 2026 at 3:14 PM Khaled Alam khaledalam.net@gmail.com
wrote:
Hi Tim,
With regard to the RFC policy, I just added the necessary “Abstain”
option to the vote.I'm also noting some rendering issues in the RFC, particularly in the
Proposal section, where the “bullet point list” does not render
properly, due to the line-breaks in the markup. I'm also seeing that you
try to use the markdown syntax for inline code. That doesn't work in the
Wiki, since it doesn't speak markdown. When showcasing PHP code, I
recommend using <php>isset()</php> tags (<php> XML tag). For
non-PHP-Code ''BP_VAR_FUNC_ARG'' (two single-quotes works). You might
want to clean-up both of these, it will make the RFC look much nicer and
more approachable.Please note that your RFC update is considered a major change, so it
needs 14 days of “cooldown” for discussion, before the RFC can go to
vote.Thanks for the feedback, I just fixed the RFC
https://wiki.php.net/rfc/const_object_property_write rendering issues.Best regards,
__Khaled Alam
Hi
Am 2026-04-04 02:52, schrieb Khaled Alam:
I'd like to bring attention back to this RFC, which has been updated to
v0.2 based on prior feedback:Thank you. The updated RFC makes sense to me and with the removal of the
FOO[123] = 'bar';support I don't have any further technical concerns.With regard to the RFC policy, I just added the necessary “Abstain”
option to the vote.I'm also noting some rendering issues in the RFC, particularly in the
Proposal section, where the “bullet point list” does not render
properly, due to the line-breaks in the markup. I'm also seeing that you
try to use the markdown syntax for inline code. That doesn't work in the
Wiki, since it doesn't speak markdown. When showcasing PHP code, I
recommend using <php>isset()</php> tags (<php> XML tag). For
non-PHP-Code ''BP_VAR_FUNC_ARG'' (two single-quotes works). You might
want to clean-up both of these, it will make the RFC look much nicer and
more approachable.Please note that your RFC update is considered a major change, so it
needs 14 days of “cooldown” for discussion, before the RFC can go to
vote.Best regards
Tim Düsterhus
Le 21 juin 2026 à 20:33, Khaled Alam khaledalam.net@gmail.com a écrit :
Hi all,Reviving this thread. The v0.2 RFC https://wiki.php.net/rfc/const_object_property_write (object property writes on constants only;
array/dim writes removed) addressed Tim's concerns, and the 14-day cooldown has long passed.Unless there are further objections, I intend to open voting on Monday, 29 June 2026. 2/3 majority,
targets PHP 8.6, two-week vote.RFC: https://wiki.php.net/rfc/const_object_property_write
PR: https://github.com/php/php-src/pull/20903Best regards,
__
Khaled Alam
Hi,
The RFC talks only about global constants. What about class constants? It is somewhat cumbersome to get a mutable object in this position, but it is nevertheless possible, and, at least for consistency, it should be ensured that they are treated the same way as global constants:
—Claude
Hi,
The RFC talks only about global constants. What about class constants? It
is somewhat
cumbersome to get a mutable object in this position, but it is
nevertheless possible, and,
at least for consistency, it should be ensured that they are treated the
same way as global constants:
Hi Claude,
Good point, thanks. I've extended the implementation so they're handled the
same way; both forms
from your example now work:
c::o->b = 42;
$c::o->b = 42;
One consequence worth flagging: enum cases are class constants, so
unset(Enum::Case->value)
(and writes to readonly case properties) now raise the regular runtime
readonly-property Error instead of
the old compile-time "temporary expression" error, i.e. identical to $x =
Enum::Case; unset($x->value);.
Enum case properties remain immutable.
I've updated the PR (#20903) and bumped the RFC
https://wiki.php.net/rfc/const_object_property_write to v0.3 to cover
this. Since it widens the scope,
I'll restart the discussion cooldown and push the vote date back
accordingly.
Best regards,
__
Khaled Alam
On Mon, Jun 22, 2026 at 12:01 AM Claude Pache claude.pache@gmail.com
wrote:
Le 21 juin 2026 à 20:33, Khaled Alam khaledalam.net@gmail.com a écrit :
Hi all,Reviving this thread. The v0.2 RFC
https://wiki.php.net/rfc/const_object_property_write (object property
writes on constants only;
array/dim writes removed) addressed Tim's concerns, and the 14-day
cooldown has long passed.Unless there are further objections, I intend to open voting on Monday, 29
June 2026. 2/3 majority,
targets PHP 8.6, two-week vote.RFC: https://wiki.php.net/rfc/const_object_property_write
PR: https://github.com/php/php-src/pull/20903Best regards,
__
Khaled AlamHi,
The RFC talks only about global constants. What about class constants? It
is somewhat cumbersome to get a mutable object in this position, but it is
nevertheless possible, and, at least for consistency, it should be ensured
that they are treated the same way as global constants:—Claude