Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127864 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 26F3E1A00BC for ; Thu, 3 Jul 2025 16:28:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1751560010; bh=TkP9h6L57saeP3UqJU1J2Pb9rRg6zQi0o2E7bpSLoHE=; h=Date:From:To:In-Reply-To:References:Subject:From; b=FQWpd3fgphXYaWpGAM4FruhNdSVRdkHu4VF+km6BWsFd43tnM1gqBACLiRFKah52X ILv29pL9xnnoBO5RbkMeAuwIQJ9FBwntinrBbxPrBQ5p2LFhyRYVBWf3hYecboV8XW 6f3+cn5Z6BzYLfhjBEgmYK3WmbRhN4GfTtwSVS2WBUCqg3xOPyjlrQigOH51H7n5z2 v6JSrZgBwpOVDD4zTDhQT+Jal4Dcj81hKTMNe5erN2ArKLsRN4O9D6J3MEilynziOZ SVw8KY5RJSwdNiySpnKL+cI1U8OeZGCGfaVvkrTVde/pR2+rWLiQuN95B/SZslBBqO O8/9CC7c4CI7g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C39361801E0 for ; Thu, 3 Jul 2025 16:26:49 +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=-2.8 required=5.0 tests=BAYES_00,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.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) 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 ; Thu, 3 Jul 2025 16:26:39 +0000 (UTC) Received: from phl-compute-10.internal (phl-compute-10.phl.internal [10.202.2.50]) by mailfout.phl.internal (Postfix) with ESMTP id 69474EC0436 for ; Thu, 3 Jul 2025 12:28:31 -0400 (EDT) Received: from phl-imap-02 ([10.202.2.81]) by phl-compute-10.internal (MEProxy); Thu, 03 Jul 2025 12:28:31 -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=1751560111; x=1751646511; bh=ksqyEL2fbQj5Besh7VE3M 2kJ1deALcez0qqm7Au7fUw=; b=fJ2xldvn/88/iDoDTvtFxrNnq2kdfurEN2uYb KfAAs0lE3WbLkjSj044UFjDeunVeAMaPZQdhL+QhbtgBiGI0z18WY2ha3rgwD6B7 ZMZrM1WmX9PgO8pODT8nIEfOH8xnPZNBBcwqITmQwrll07xs51UvugV1bsI6G52F 6Mq5uECF8GHspxb0s2zPfn84tRU1KLT3BcW0kO9gdoh8JlEO3BhsT9vr60j34sER PF/VslLY5+nRLucMDBugZ41KliUDzpWcBd7CzL/DUB1NBRdmIZZ2mEOb8NxG+i7B HsxwHWZaD1lESnFTHEVcWJCq0MIFBfDoiy//EUs8ZnbCEvK1g== 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-sender :x-me-sender:x-sasl-enc; s=fm2; t=1751560111; x=1751646511; bh=k sqyEL2fbQj5Besh7VE3M2kJ1deALcez0qqm7Au7fUw=; b=lXyCaDrtddkcQJcD4 Krs4lZlIsycQJtGfWQFgmlx47gu4Br3CHFuFo1Ngz8LS6UOVf3CbgnNKZDf7Cxgx fSvlx4Sc+4/rCXXGLMqYAfaOdmqKx2gif+umPIzu93/I8/4UFoMK1tg/EBUPTmcN PGatqYHT6V2FteA6LFLnrA+iRSTQI+Yhmcw/UNje1OB5+AodXrKF6sqj4ScWvy+Z 4JBQnyGFVaLjih+b7Qxp2IjTqUpOB8YVzIllhaD8JnsOUj6wBG9+QM/cPrmPoKBN h4wpIw4+O5XqwOnps8a9zJgqe6jlvhYgNq5yxw1yyUfPiCXdbRMIX/9b1A00V8qM xspzg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgddvtdejhecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefoggffhffvkfgjfhfutgfgsehtjeertdertddtnecuhfhrohhmpedfnfgrrhhrhicu ifgrrhhfihgvlhgufdcuoehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomheqne cuggftrfgrthhtvghrnhepueehjeduleetleeiheelleelkedvtdfgtedtgefhgfeghedv jeegjeefffeuhfdvnecuffhomhgrihhnpehgihhthhhusgdrtghomhenucevlhhushhtvg hrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehlrghrrhihsehgrghrfhhi vghlughtvggthhdrtghomhdpnhgspghrtghpthhtohepuddpmhhouggvpehsmhhtphhouh htpdhrtghpthhtohepihhnthgvrhhnrghlsheslhhishhtshdrphhhphdrnhgvth X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.phl.internal (Postfix, from userid 501) id 1C7CF700069; Thu, 3 Jul 2025 12:28:31 -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 X-ThreadId: T13a9b6ebd1dfd435 Date: Thu, 03 Jul 2025 11:27:54 -0500 To: "php internals" Message-ID: <1cfc477a-781f-40e9-9e37-dd748ef261be@app.fastmail.com> In-Reply-To: References: Subject: Re: [PHP-DEV] [RFC idea] Target-aware attributes Content-Type: text/plain Content-Transfer-Encoding: 7bit From: larry@garfieldtech.com ("Larry Garfield") On Wed, Jul 2, 2025, at 5:26 PM, Andreas Hennings wrote: > This topic was discussed in the past as "Declaration-aware > attributes", and mentioned in the discussion to "Amendments to > Attributes". > I now want to propose a close-to-RFC iteration of this. > (I don't have RFC Karma, my wiki account is "Andreas Hennings (donquixote)") > > ----- > > Primary proposal > ============= > > I propose to introduce 3 new methods on ReflectionAttribute. > > static ReflectionAttribute::getCurrentTargetReflector(): ?Reflector > Most of the time, this will return NULL. > During the execution of ReflectionAttribute->newInstance(), it will > return the reflector of the symbol on which the attribute is found. > (in other words, during > $reflector->getAttributes()[$i]->newInstance(), it will return > $reflector.) > During the execution of > ReflectionAttribute::invokeWithTargetAttribute($target, $callback), it > will return $target. > If the call stack contains multiple calls to the above mentioned > methods, only the closest/deepest one counts. > (This means that php needs to maintain a stack of reflectors.) *snip* > Other alternatives > ====================== > > In older discussions, it was suggested to provide the target reflector > as a special constructor parameter. > This is problematic because an attribute expression #[MyAttribute('a', > 'b', 'c')] expects to pass values to all the parameters. > > Another idea was to provide the target reflector through a kind of > setter method on the attribute class. > This can work, but it makes attribute classes harder to write, because > the constructor does not have all the information. > It may also prevent attribute classes from being stateless (depending > how we define stateless). > > > Userland implementations > ========================= > > One userland implementation that was mentioned in this list in the > past is in the 'crell/attributeutils' package. > This one uses a kind of setter injection for the target reflector. > See > https://github.com/Crell/AttributeUtils/blob/master/src/FromReflectionClass.php Hey, I know that guy! :-) > Another userland implementation is in the > 'ock/reflector-aware-attributes' package. > https://github.com/ock-php/reflector-aware-attributes (I created that one) > This supports both a setter method and getting the target reflector > from the attribute constructor. > > The problem with any userland implementation is that it only works if > the attribute is instantiated (or processed) using that userland > library. > Simply calling $reflector->getAttributes()[0]->newInstance() would > either return an instance that is incomplete, or it would break, if > the attribute class expects access to its target. I am unsurprisingly in favor of finding a solution here, as there are innumerable cases where you need the reflectable that the attribute is on; the most common for me is using the name/type of a property as defaults for the attribute. However, I am very skeptical about a stateful global value as the solution. We've tried very hard to remove those from PHP, mostly successfully. Adding another one back in feels like a major step backwards, and a great place for weird bugs to hide. A setter method injection is what I did in AttributeUtils, because it was the only real option. Alternatively, I suppose core could use property setter injection (either a magically named property like $__reflector, or a property that itself has an attribute on it, etc.). That would allow it to be set before the constructor is called, and with property hooks would allow processing either immediately or later in the constructor. The downside here is that Attribute are, generally, serializable, but a Reflection object is not. So if someone wanted a serializable attribute they would have to accept the property, use it, and then remember to unset it at some point. That's clumsy. --Larry Garfield