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

Hi internals,

I opened PR #20903 to address GH-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.

  • 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

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

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.

    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.

Online PHP editor | output for ARMMS

    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-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:

PHP: 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

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 isset() tags ( 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 rendering issues.

Best regards,

···

__

Khaled Alam

Hi all,

Reviving this thread. The v0.2 RFC (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

__

Khaled Alam

Hi all,

Reviving this thread. The v0.2 RFC (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,

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

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 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

__

Khaled Alam

Hi

Am 2026-06-28 09:50, schrieb Khaled Alam:

I've updated the PR (#20903) and bumped the RFC
<PHP: 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.

Thank you. I've had a look at the changes you made and I'm noticing that you added a second voting widget by accident. Can you double-check the diff and revert the accidental changes?

I'm also noticing just now that the RFC is not listed in the RFC overview at PHP: rfc (and itself has the status “Draft”). Can you make sure to list the RFC in “Under Discussion”? It could technically be argued that the discussion didn't properly happen, but as you made a recent change that resets the cooldown anyway and there's still a bit of time until feature freeze that shouldn't be an issue.

Best regards
Tim Düsterhus

Hi

Thank you. I’ve had a look at the changes you made and I’m noticing that
you added a second voting widget by accident. Can you double-check the
diff and revert the accidental changes?

https://wiki.php.net/rfc/const_object_property_write?do=diff&rev2%5B0%5D=1775894869&rev2%5B1%5D=1782632547&difftype=sidebyside

I’m also noticing just now that the RFC is not listed in the RFC
overview at https://wiki.php.net/rfc (and itself has the status
“Draft”). Can you make sure to list the RFC in “Under Discussion”? It
could technically be argued that the discussion didn’t properly happen,
but as you made a recent change that resets the cooldown anyway and
there’s still a bit of time until feature freeze that shouldn’t be an
issue.

Hi Tim,

Thanks for catching these. I removed the accidental duplicate voting content and added the RFC to the “Under Discussion” section of the RFC overview page.

Best regards,

···

Khaled Alam

Hi

On 2026-07-11 12:38, Khaled Alam wrote:

Thanks for catching these. I removed the accidental duplicate voting
content and added the RFC to the “Under Discussion” section of the RFC
overview page.

Thank you. You missed the status in the RFC itself, which I have now done for you: PHP: rfc:const_object_property_write

I consider your change on Saturday to be the last (major) change to the RFC. You may then open the vote on on July 25th. Vote must start no later than July 28th to meet the deadline for PHP 8.6. Don't forget to send the “intent to vote” 2-7 days before actually starting the vote.

Best regards
Tim Düsterhus

Hi Tim and internals,

Thank you all for the feedback and discussion on the “Const object property write” RFC over the past weeks

The RFC text has been stable since last weekend, and I believe the remaining questions have been addressed.

I therefore intend to open the vote on Saturday, July 25th. The voting period will run for the standard two weeks.

This gives us time to complete the vote and merge in time for the PHP 8.6 feature freeze.

RFC: https://wiki.php.net/rfc/const_object_property_write

If there are any final objections or concerns that should be resolved before the vote opens, please raise them in the next few days so I can address them before Saturday.

Best regards,

···

__

Khaled Alam

Hi internals,

As announced previously, I am now opening the vote for the RFC “Allow Object Property Writes on Objects Referenced by Constants.”

RFC and voting: https://wiki.php.net/rfc/const_object_property_write

The vote will remain open for the standard two-week period and will close on Saturday, August 8, 2026, at 23:59 UTC.

I would like to thank everyone who participated in the discussion and provided feedback. The comments and suggestions helped improve the proposal considerably.

Best regards,

···

__

Khaled Alam

__

Khaled Alam

Hey Khaled

···

__

Khaled Alam

Hi Khaled

···

On 25.07.26 15:48, Khaled Alam wrote:

As announced previously, I am now opening the vote for the RFC “Allow Object Property Writes on Objects Referenced by Constants.”

RFC and voting: https://wiki.php.net/rfc/const_object_property_write

The vote will remain open for the standard two-week period and will close on Saturday, August 8, 2026, at 23:59 UTC.

I would like to thank everyone who participated in the discussion and provided feedback. The comments and suggestions helped improve the proposal considerably.

You seem to be missing the abstain option, which is mandatory since https://wiki.php.net/rfc/rfc_vote_abstain.

Ilija