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