[php-src] PR #20903: GH-10497 (const obj->prop write) - language change notes

php.internals

Khaled Alam

229 days ago
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*

Tim Düsterhus

226 days ago
Hi On 1/15/26 07:36, Khaled Alam wrote:
> 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

Ilija Tovilo

222 days ago
Hi Tim On Sun, Jan 18, 2026 at 1:28 PM Tim Düsterhus <tim@bastelstu.be> wrote:
> > On 1/15/26 07:36, Khaled Alam wrote: > > 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

Tim Düsterhus

222 days ago
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

Khaled Alam

150 days ago
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* On Thu, Jan 22, 2026 at 10:33 AM Tim Düsterhus <tim@bastelstu.be> wrote:

Tim Düsterhus

145 days ago
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: > > https://wiki.php.net/rfc/const_object_property_write
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

Khaled Alam

143 days ago
Hi Tim, On Apr 9, 2026, 10:39 AM, Tim Düsterhus <tim@bastelstu.be> wrote:
> 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* On Thu, Apr 9, 2026 at 10:39 AM Tim Düsterhus <tim@bastelstu.be> wrote:

Khaled Alam

72 days ago
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:

Claude Pache

71 days ago
> 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/20903 > > Best 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: https://3v4l.org/QhM1L —Claude

Khaled Alam

65 days ago
> 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:
> https://3v4l.org/QhM1L
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: