Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:125795 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 qa.php.net (Postfix) with ESMTPS id 592801A00BD for ; Mon, 14 Oct 2024 02:58:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1728874819; bh=lmTj4a7IM69Gh1AuHQz0/S9wsAfE/N8/dqFG2s3IkV8=; h=Date:From:To:In-Reply-To:References:Subject:From; b=ITy4/EmbnP8ncJj4q1IgLOVxzUydEU0sWpn1DWHafVHgqJAscZ2yPSzMq24O2hbGr tluFF+wiRW5VRjooBiJqmmx8uM+fwxJEb5sEz0ZlYtWl1KfIDrNU8PIsbmUvjScaxX G+Qy/q9XehzY5i8CHF+dvuCBf2fnjQ/H8vJ8quCEmDZov37G2QwBJ5qXuNGU9XXJkN 7B6uW7zHDnZdemCqRUZFvt1m3SnlhTq/C1UwLJ1c1nwQYUfGAJ9d+LD+/oYcRhBafw T+zwQgcRkMZzmM/w3EcU2n7SLc7t36ngHTPHz8Z6erhUtT1S1CIMUymrFnEchPcg4J bL/AD/KBIPr3Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id EB423180061 for ; Mon, 14 Oct 2024 03:00:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS,SPF_NONE autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fhigh-a2-smtp.messagingengine.com (fhigh-a2-smtp.messagingengine.com [103.168.172.153]) (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 ; Mon, 14 Oct 2024 03:00:18 +0000 (UTC) Received: from phl-compute-01.internal (phl-compute-01.phl.internal [10.202.2.41]) by mailfhigh.phl.internal (Postfix) with ESMTP id 37FB7114018A for ; Sun, 13 Oct 2024 22:57:58 -0400 (EDT) Received: from phl-imap-06 ([10.202.2.83]) by phl-compute-01.internal (MEProxy); Sun, 13 Oct 2024 22:57:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= garfieldtech.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to; s=fm2; t=1728874678; x=1728961078; bh=K7l1lsMIUjvw2rYDWcriq dr+pHlw/z9wjcWA8uo5YAw=; b=ZNqKfTYNcUPaH5NR2v4WU/0vNcl4SBGuHSSxb SLVyn2Lx3ybXZnKjW3L9vaVyTRJ1ezrFaZsJTqPFlfa5hvgOAmQQQwmgaH+QWxZe Vrm6mO3IhyhiWgZczVPViBfBiOzs/gvyO4gVGBuHlbJS250qk0SqhZrATih8OChn DBKb7zoQV/rdtvVaMSWRPejsZPzEVa6XykHIbeZWrUWUtfQE+cgeP/5JTz7MnOId uaEjhBQz51APaxdBv56QShKZLKme21y0fOXFarPaXFXgBuGF17EG8FZzsO7wGvxc VY+OsbUSwXVTLuU6xj/CESNSfQVGcy6Oso0+hIZvcKX1aQC7w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm2; t=1728874678; x= 1728961078; bh=K7l1lsMIUjvw2rYDWcriqdr+pHlw/z9wjcWA8uo5YAw=; b=b oRZQU/eqazr7admmxvfImhSv3VeCWUl8s1mmhsWc3B7BXW8tZXUPKeLG48X9+z9b K0y0WPm0IULTC6ZAvjb1GzGNJs5eCwX/px2HQUKgGL1UNNU/FmM/y6uvuoJoDU6K yfua+byFFkXTh68rRmPsu0a4pedVPSZL+8Y8FTgELVWPdlQsasnRz35FThnPKKLX mM99mEvBiL3njXNOoh+iQ3K1PnevCqIHdrsrha/aETppz2POoZYxYMly8rQaU3Ou w7/sPdyfQFAzLcYpgayeELsTuiLwPkafHTESJsTyC1MU2dhEeh+HLweezIZg38ks pGNhTUHuegmP1TkaJAUBQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeftddrvdeggedgieehucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggvpdfu rfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnh htshculddquddttddmnecujfgurhepofggfffhvffkjghfufgtgfesthejredtredttden ucfhrhhomhepfdfnrghrrhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfih gvlhguthgvtghhrdgtohhmqeenucggtffrrghtthgvrhhnpeeuheejudelteelieehleel leekvddtgfettdeghffggeehvdejgeejfeffuefhvdenucffohhmrghinhepghhithhhuh gsrdgtohhmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhho mheplhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtohhmpdhnsggprhgtphhtthhope dupdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehinhhtvghrnhgrlhhssehlihhs thhsrdhphhhprdhnvght X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id D480629C006F; Sun, 13 Oct 2024 22:57:57 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Sun, 13 Oct 2024 21:57:37 -0500 To: "php internals" Message-ID: In-Reply-To: References: <2A7CF24F-3AE3-4125-965F-C65431C42DFB@gmail.com> <30a41608-a1ea-40a9-8d2a-c53c508cd89f@jnvsor.net> Subject: Re: [PHP-DEV] Asymmetric visibility is a BC break Content-Type: text/plain Content-Transfer-Encoding: 7bit From: larry@garfieldtech.com ("Larry Garfield") On Sun, Oct 13, 2024, at 9:37 PM, Valentin Udaltsov wrote: > First of all, I have already agreed above that PHP does not have a BC > break here. Now we are discussing the potential problems in the PHP > ecosystem and how they could be mitigated. Ilija and I have discussed this issue a bit. The first issue is that isPublic() technically means "does this property have the public flag set," and nothing more. Prior to 8.1, that implicitly also meant "can the property be read and written to from public scope," because of how properties worked. (And same for isProtected().) That implicit assumption became invalid in 8.1 with readonly, which stealth introduced limited and not fully designed asymmetric visibility as well as properties that could not be set multiple times from any scope. Full aviz in 8.4 doesn't change that. It just makes the previous assumption change more apparent. The fact that no one seems to have reported it as an issue until now suggests it's not a particularly widespread problem. In practice, if someone is using reflection to determine the visibility of a property, they'll be writing to it through reflection as well if at all. The best solution here is probably to just clarify the docs, which I will do as part of the aviz docs that I have already been working on. cf: https://github.com/php/doc-en/pull/3828 The second issue is that the behavior of isProtectedSet() / isPrivateSet() was not as clearly defined in the RFC as it should have been. That's on us for not being clearer, as we apologize for the oversight. Those methods follow the low level pattern of isPublic() , that is, they just report of a given flag is set, not what the implications of that flag in various contexts are. That is consistent with the rest of the reflection API, so we feel that is best left as-is. That still means the "so can I read/write this property or not?" question has no simple operation for it. Again: it never did, we just kinda sorta had it indirectly and implicitly. For that we feel the best answer, as well as least disruptive given we're in RCs, is dedicated methods as Ilija has already described that take all property behavior and context into account. (isReadable and isWriteable.) As a reminder, the concept is: $rProp->isReadable($obj); // Can this property on $obj be read from the calling scope? $rProp->isReadable($obj, 'static'); // Same as previous. $rProp->isReadable($obj, null); // Can this property on $obj be read from global scope? $rProp->isReadable($obj, Foo::class); // Can this property on $obj be read from code inside class Foo? $rProp->isWriteable($obj); // Can this property on object $obj be written from the calling scope? $rProp->isWriteable($obj, 'static'); // Same as previous. $rProp->isWriteable($obj, null); // Can this property on object $obj be written from global scope? $rProp->isWriteable($obj, Foo::class); // Can this property on object $obj be written from code inside class Foo? cf: https://github.com/php/php-src/pull/16209 (The use of null to indicate global scope is borrowed from Closure::bind(), which does the same.) These methods do runtime analysis to see if a property should be readable/writeable. Specifically: isReadable() * Checks that the property is readable from the passed scope * Checks that the property is initialized (i.e. not typed and never written to) * Checks that the property is not virtual or has a get hook isWritable() * Checks that the property is writable (respecting symmetric and asymmetric properties) from the passed scope * Checks that the property is not readonly, is not yet initialized, or is reinitializable (__clone) * Checks that the property is not virtual or has a set hook Of note, this does not absolutely guarantee that a read/write will succeed. There's at least two exceptions: One, some PHP built-in classes have effectively immutable properties but do not use `readonly` or `private(set)`. Those would not be detected here, until and unless they are updated to use the now-available mechanisms. (See, eg: https://github.com/php/php-src/issues/15309) The other is that a get or set hook may throw an exception under various circumstances. There is no way to evaluate that via reflection, so it's a gap that will necessarily always be there. Whether those methods are OK to add in the RC phase or if they should be left to early 8.5, and if they would need a formal RFC, is up to the RMs to decide. RMs, what is your preference? --Larry Garfield