Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128340 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id E5AAB1A00BC for ; Thu, 31 Jul 2025 11:13:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1753960298; bh=Nzc617QWxt1kJEhz+47rRwBHEzp37o/UhGGLVKlMWfA=; h=References:In-Reply-To:From:Date:Subject:To:From; b=RKJhwYTGV+h/+YjStPRwGWKq6uINnvLjizboPMd+IWoixK7K33p7ZILB1/bFSWLf0 Qxft/hpk/+LnoUpBbFJIx+zwPJkiHxIIuaqWmJRZAwoZFNC6h1E00inQ57BK7TKxON wUpHPwaJlRC5SSLdoZsBkjYDpmtPSmzpqb9U9wZ77fWEPC9vZxKgt7zOjj5u9fgNHY MRNKW1wNLP8U3MePFNTAYukbs/ZEyptojork6WGJLCrKdSts/lD3pTE5ogLHWt81Nv Uske0p2apTEFd3XwqmLHIZ0BMQ8N0H1bo26psD8R1n3iroi8gi+SNUikpRPw4qHQv6 c2jqj3RVpPmhw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EBDD5180054 for ; Thu, 31 Jul 2025 11:11:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-qv1-f47.google.com (mail-qv1-f47.google.com [209.85.219.47]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 31 Jul 2025 11:11:37 +0000 (UTC) Received: by mail-qv1-f47.google.com with SMTP id 6a1803df08f44-707453b031fso2703616d6.1 for ; Thu, 31 Jul 2025 04:13:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1753960399; x=1754565199; darn=lists.php.net; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=cbi/n4xLfEBX8tv8mFZ0U5rkEc+ciXRUf2AJ/DQ8dEI=; b=QFtmOU49gTxqkd+Pw+URIe+EpYlP+M/UuAY2tQ9HvspTYAP38FDlQ6EMerZP/WOrW4 Y8ThaoZ1Wgr3F3SmWcMzRlY+BIYP3Bfze3CpNRUBe1tbTobtkUTG15SHf9vzo5aniEvE h7TEUbvpaXzZb+WJqipjz38w/yZeiNyDbIdxMIgrxmpp6LyBiFrmkxHKyVV5VvVibM3x gFcV52EOlEhfoVr281dnaOBldrFrfQMVc8UTj7AAcCmjf4awFjOlu9BLiE5bUGvJV7lf i5HE7wWyuFHzHCwMzSePDNbEthzZjjDtqUOwUMLEYfuTPeutGyS+zxC0sA8IDhtOK3v4 HZfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753960399; x=1754565199; h=content-transfer-encoding:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cbi/n4xLfEBX8tv8mFZ0U5rkEc+ciXRUf2AJ/DQ8dEI=; b=nG9lCJeM3UcyzVY40Ba6B7CxcqoTf7VwZ4q+1UNhlKDOvHhNBmmnILv0ycwaoxr2fP 0gdorNuJ1IbaL6sh1M/oVFSGe7TqtQdZQ/zg4F0GKGq5MfMELPGj6amZgoM2EJrpNygn /q9nRnyzgXsRuxEwgYtx4gMO4vjoOL9vM14QHDI9WXJmDP+Efu/gwkgU65Y8Atb0HEEK V1psyww0OmbuHECubonjnVfUhdfQrXr2eARQwWNZCjbWY2SDCFzGWY5KS8bSTP3HyRXp b35oGIaZAGYz8JjpPcSA3eXN/Z/ozDeCnTLx82UF3NPA2zNXK9qbjMEssEAGLfucWtoG nuNA== X-Gm-Message-State: AOJu0YyynUgOKxlOmJiO4Pxrw4SEWpxDcryO1iTta+LQGDSH5W8eTbkF hREDBPOyMi7zO88zc3Xz8wmlwOyloG+roxaCvbg858eItqBANmUkdVkRyoYcK9y0Qp4nM480y8o LPlvRE1Ct3wqQf7HvOrlKjjcfsnPUGBkgu42A133VQA== X-Gm-Gg: ASbGncvpIgr55pROIZQn8IFvJsFR4FHL+ppUYR1Mi5zXfx6qHShClSDL55tQP73lyU/ 9djEkkzXu9E7JgNiunsmCdS4u9zaYMlo8qrllAcIPQ10Y5Nsas2MJNhgd17sD1SJZqXC19AQ8wq OmT3KDIuGL5cTvEV5oBb4J5L8edzKXzE5VWCJ8cBvH367I341OSdFMG2tvU7Xtz2tICbSEh/HrC t16kFlfc3k/DcvELPi+I4AonLfyL3qEYkE4JPRTIw== X-Google-Smtp-Source: AGHT+IHCfTEcQcDQAaGyTpYQY1Wz6L8kmx0XUzCbCfbcnmHb/tYhtuq/bMxaa7qQJehLh9LKlnvMkgklToiWw9bcQQw= X-Received: by 2002:ad4:5aaf:0:b0:707:5759:848b with SMTP id 6a1803df08f44-70766e391dfmr85647526d6.12.1753960398443; Thu, 31 Jul 2025 04:13:18 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <1d8574f9-8171-4398-96d5-70058deaccb0@app.fastmail.com> In-Reply-To: <1d8574f9-8171-4398-96d5-70058deaccb0@app.fastmail.com> Date: Thu, 31 Jul 2025 13:13:07 +0200 X-Gm-Features: Ac12FXx6Y1VZj7UP71mxD5E4dGmzsfZmnMjdg2GsbXu2OwwT43k_9TL3Qt7Mu_0 Message-ID: Subject: Re: [PHP-DEV] references & arrays + hooks To: PHP internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: tovilo.ilija@gmail.com (Ilija Tovilo) Hi Rob On Thu, Jul 31, 2025 at 10:48=E2=80=AFAM Rob Landers wr= ote: > > Currently, this is not allowed by PHP: > > class Foo { > public function __construct( > public string &$ref { get =3D> $this->ref ?? 'null'; set =3D> $this= ->ref =3D $value; } > ) {} > } > > After the release, I'd like to propose an RFC that allows using reference= s with hooks: As we've considered references extensively during the hooks RFC, allow me to add some context. > this will probably necessitate a new zval type, determined at runtime (it= will not be exposed to users). The impact for new zval types is gigantic, and it's been avoided for decades. I don't think it's technically necessary either. We're already recording zend_reference.sources, which is a list of properties that store the reference. This is used for type coercion when assigning to a reference that may be stored in a typed property. class C { public int $prop; } $c =3D new C(); $prop =3D 42; $c->prop =3D &$prop; $prop =3D '43'; var_dump($prop); // int(43) You may be able to use the same mechanism for set hooks. This would need to be extended to store the actual object containing the reference, so that the set hook may be invoked. However, there are some issues. For example, what do you do when a reference is assigned to multiple hooked properties? class C { public int $prop1 { set =3D> $value + 1; } public int $prop2 { set =3D> $value + 2; } } $c =3D new C(); $prop =3D 42; $c->prop1 =3D &$prop; $c->prop2 =3D &$prop; $prop =3D 43; // What happens now? Typed properties handle type conflicts gracefully [^1], but graceful handling for hooks is less clear because each hook can transform the assigned value. You might allow assignment only when the reference is bound to a single hooked property, but then this isn't a general solution. I suppose you may also require all set hooks to assign the reference to an identical value. Another current limitation is reference assignment. `$c->prop1 =3D &$prop;` from above doesn't actually work. That's because hooks currently allow &get, i.e. retrieving the reference stored in a hooked property (`$prop =3D &$c->prop1`), but they don't allow setting the property reference, which is semantically distinct. set(&value) is not sufficient because the hook implementation must know whether to assign to the backing store through a direct assignment, or =3D&. set(&value, bool $byRef) would work, but is quite clunky. You also mention arrays. This approach does not solve the issues we've outlined in the RFC [^2]. In particular, indirect modification may still hide mutations from set hooks. Even if we can fix this and make every mutation call the set hook, the significant ergonomic issues of understanding _how_ the array changed remain, along with performance issues due to array separation. Disregarding arrays, this approach might not be too complex. However, given that arrays are by far the most used type when it comes to references, them being exempt makes this feature far less useful. That's the main reason we didn't pursue this idea further, and I remain quite convinced that arrays are unworkable. Ilija [^1]: https://3v4l.org/defVI [^2]: https://wiki.php.net/rfc/property-hooks#arrays