Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126505 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 B464E1A00BC for ; Tue, 25 Feb 2025 21:14:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1740517933; bh=Urju7lCzYx8VsmO0E0q056d8a8Y8M6lBUO6zQ16IqYI=; h=Date:From:To:Subject:From; b=MZ+khyEAY693tDpp5i5dUKR9ruQaGVkqKPXggv76QXUxt53R0HoAiHNrX2mZ/zChZ OPO55Fzd1feYIZZJmGu3MxZz2NzkFXzoGiV3D1DfYm2fzsQ8CjGnWJTjc/7dYqBHa9 FbCj6ZW1vFo51isE9iXsp4SzVnbCoZZJaAXgPCWaf0Fm1Pbgdz518ormSqf405pdTh +K3WGIBXLjswNAkV6Bh/Cm54eYLM4bhruD+eN64RDH5fk3wDnrgsR+htr2YRYpocRn dDnG0ikFNKSB+tp9vdVZIlKe7gQxQWLrxNRWnkahAmI4MLkGVHQd60I32gwQz1iJ8D vc4xcS23SUqgA== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 192DB1801D5 for ; Tue, 25 Feb 2025 21:12:13 +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=-4.3 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS, FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from fout-a7-smtp.messagingengine.com (fout-a7-smtp.messagingengine.com [103.168.172.150]) (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 ; Tue, 25 Feb 2025 21:12:12 +0000 (UTC) Received: from phl-compute-07.internal (phl-compute-07.phl.internal [10.202.2.47]) by mailfout.phl.internal (Postfix) with ESMTP id A5CB713809B4 for ; Tue, 25 Feb 2025 16:14:50 -0500 (EST) Received: from phl-imap-07 ([10.202.2.97]) by phl-compute-07.internal (MEProxy); Tue, 25 Feb 2025 16:14:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fastmail.com; h= cc:content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:message-id:mime-version:reply-to:subject :subject:to:to; s=fm1; t=1740518090; x=1740604490; bh=H18dSlxc2E GbOMUgDzbzgv8UEw4pwq7JKkk3wC05hf4=; b=PcMkHfQZSn+F1eOPvvJFvqGscl v877qOn6h4sTD8OeyXzNQqUmoIi7QOFgQ8fM2pFhWyLVN2YsAvbma8IDIvq86pBd GsfUJ1d1MEk3XqPkyfkGMSWv1ip676Zzhe9vd2Fh3KSwqc/ZglEl9WSJGFHXrU3P TNSYcJF9XrrbhZrNJZvGYOQiSrhgoMYTHkYVmqJUAGUO1fczPo3gmz1O3nRBJM0b SreuulWJrCQWNsRFPeVURuu7C4Ub5exT0kvni3DRQ8pBY7/qBgeE5kL1xtRrFcTM sPJF5f9Rf5t+xxBoJ5nR8HaShDkRX0Jdirf99RA31v+NjjfRxsChzUWVcfKw== 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:message-id:mime-version:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t= 1740518090; x=1740604490; bh=H18dSlxc2EGbOMUgDzbzgv8UEw4pwq7JKkk 3wC05hf4=; b=Yy4fgEqtWMAwvVsd2O/bF8Rj4q0lsIIeuvDhd1EmvBz5qObNsnz gSvQ/z5OlOaGa+frQuI+d/k7ZwXgBwcB0jlcM750T5DFDluXjlolsoS1x4+o9deC NGy7c5248G4pIQrUB4+J/txir99lzYUgdLQ3SUlzSTCq9e+d18mHACKnQdH5FOzZ 6coaBbQ6BMKtqTu0cDfu2lcfuPJ82PVeG4Ny0P1F3i9uGj818VySPmTAln4VOrKb EUSYaoI04dDztGKO7TJ9xjRsVj7MRQ5Ji1EVj0SNq950ILfoDhxTD6BDRcr/44kY mwSjhFdvK8x7AEzBcjPa2mhWne9Vz3JIIrw== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdekvdejhecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecunecujfgurhepofggff fhvffkufgtgfesthejredtredttdenucfhrhhomhepthhighhhthdrfhhorhhkfeduledv sehfrghsthhmrghilhdrtghomhenucggtffrrghtthgvrhhnpeffffeghfegvdegfedvje ekieeiuddukeefveeiffekhefgueelgefgffdujeduueenucffohhmrghinhepghhithhh uhgsrdgtohhmnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrh homhepthhighhhthdrfhhorhhkfeduledvsehfrghsthhmrghilhdrtghomhdpnhgspghr tghpthhtohepuddpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepihhnthgvrhhnrg hlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: i35d941ae:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 63DD1BA006F; Tue, 25 Feb 2025 16:14:50 -0500 (EST) 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: Tue, 25 Feb 2025 15:13:54 -0600 To: internals@lists.php.net Message-ID: <0b408765-04c4-49ed-bd5a-bceb34a2a3f1@app.fastmail.com> Subject: [PHP-DEV] Consensus gathering: allowing unsetting of backed property hooks Content-Type: text/plain Content-Transfer-Encoding: 7bit From: tight.fork3192@fastmail.com Hello! I started GitHub issue requesting that property hooks be allowed to be `unset()`: https://github.com/php/php-src/issues/17922 While discussing in the issue it was suggested I pitch this to the mailing list, so here I am. You can review the GitHub issue so I won't rehash the whole thing here, but I'll summarize the main points for `unset()` of backed property hooks: 1. It is well-established in PHP that one can `unset()` object properties. If we cannot `unset()` property hooks - which to a consumer are indistinguishable from plain properties - then the consumer must now be aware of the object's internal implementation before doing what used to be explicitly allowed. This is both poor encapsulation and not compatible with the commonly-understood behavior of `unset()`, leading to surprising cases where a consumer of an object could cause a fatal error by trying to `unset()` a property that unbeknownst to them is implemented as a property hook. 2. Getters may perform a calculation, or fetch from a database, and cache the result in the backing value, but without `unset()` we can end up in a state where the logic to determine that value can never be executed again. The workaround is exposing a public method that contains such logic, but that defeats the point of putting logic in property hooks in the first place, and exposes internal class implementation details that should not concern the consumer. Getting and caching values is a common case in ORM layers, one of the biggest users of PHP. 3. It would be convenient to be able to `unset()` backed properties when changing data elsewhere in a class, for example to trigger a recalculation or re-fetching from the database. It's not enough to set such properties to `null` because 1) the actual type of the property may in fact not be nullable, leading to inconsistency in the property's PHP type and the database column type, and 2) in practice `null` is a real value that can come from the database, which is a distinct concept from "uninitialized at the PHP level". (This is the old `isset()` vs `is_initialized()` problem, a tired struggle going on decades now.) Some arguments raised against were internal implementation details; that `unset()` itself is a bad design choice so we should not cater to it; and that catering to `uninitialized` makes typing more complex. I can't comment on implementation details. To the last two points, I would say that for better or worse, `unset()` and `uninitialized` are part of PHP and I assume they're here to stay. Therefore if we're extending the language, we should extend it in ways that embrace, not ignore, its warts, because they're what make the language and they're what decades of developers are accustomed to. Ignoring the warts, or leaving them in the language but calling them bad practice that must be avoided, results in footguns and a language that is inconsistent with itself. (As I'm sure you're all aware, inconsistency is one of the favorite charges leveled at PHP by its detractors.) And while `uninitialized` may make types more complex, it can often be very useful, especially when filling objects from database rows - one of the most common tasks a web developer will ever do. It might be technically purer to require that objects only be created with lengthy constructors that initialize every property with strongly typed values, and `unset()` and `isset()` never be used, but for better or worse that's just not how PHP evolved. Having the flexibility of objects with uninitialized, and therefore unsettable, properties is very useful. This flexibility is part of what makes PHP so attractive and what made it so popular in the first place. In the GitHub thread it was mentioned that an RFC would be required. I've never written one, nor am I familiar with PHP internals, but I can try putting one together if there's interest.