Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127908 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 7332F1A00BC for ; Sat, 5 Jul 2025 19:53:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1751745102; bh=Ls64wSTyKLfdPYgS2XrrqTE86Dn4LDFkqrbUWBuN1Xw=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=Plm3+kjYn334x02vV9GeKQ2kKDsNRayVFeRXh6YeyiHeXVKmKdecuI35Bla7OYQvy RCTPLV2iKas7lCncyPyLISrHytxaFc5mGSSwVZuX2LSUN9nObjS6cPf+KUIe9kXKA1 9pqLnCoYYq63EpyoeozTbWGli0GQkCUTvR/TfTi8NW/uK+1Hg0hgZj0BXE520Wp+41 379ZsrRfB6rbMD5Aqg7MS5jt4+JY1BhywC6OVoOLlReYKxJwl1cb6Wxg7lG4fHgYcD 9E5b8zPuSFUHPQv3to7apaGioXVMf1fLTLxUz1pEI7J+A7XR0UYRlSm1tw7bRqS+Xy OTOk5v9kLvihw== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id A61C8180054 for ; Sat, 5 Jul 2025 19:51:41 +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, HTML_MESSAGE,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-yb1-f177.google.com (mail-yb1-f177.google.com [209.85.219.177]) (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 ; Sat, 5 Jul 2025 19:51:41 +0000 (UTC) Received: by mail-yb1-f177.google.com with SMTP id 3f1490d57ef6-e7387d4a336so1519236276.2 for ; Sat, 05 Jul 2025 12:53:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1751745212; x=1752350012; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=Ls64wSTyKLfdPYgS2XrrqTE86Dn4LDFkqrbUWBuN1Xw=; b=IUikWQaXW1C7njXRjyVBm1yWD0Nuxh2g+XiXW+n2alPYi2qrRUG2TZPN3LFzq6dUPL 60nKBEc+jpN3R7jewJyCfAJ7uljYsowjvX6d2s1gws+TMiVfss7mFAdm0cGqnElangTN Wt+slCLRSN5nGRFYEE6JdwysVo/YgX+jXjtka4hx597Bj+tKpH165YBe88vo9K51cW3x 8Kt1SJJ3NfnUw7C/NJdqb4dVM7AHl13ZhxNUMNU69zqoSiz2RDngu9CzC1S/kkwSJbX1 TVKMkd/97rs/NGybtVmTlt4Po/Eepji3Y7TddreQDfRVE5tjthaoWRvjFrM3fQY3CJdU VmLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1751745212; x=1752350012; h=cc: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=Ls64wSTyKLfdPYgS2XrrqTE86Dn4LDFkqrbUWBuN1Xw=; b=M1tYkhy/8/WmIe1CxjuuxmbD1yvCHD9RruGgKkKtBD/7IipNqt8n+cUyIVXryTensV CDIHH5U0YzttV7GhULTa/vvxW0MJbM4Tyrc7q+H45ggFJc+x/Jd3UuVWWxD2DOKO0kNS Etz8/xRRYooiOGW3kT2TtnFlnYqDOhQ8p9LU3+TIGsBKvpxZtBZjXtC37UGLKbBylPf8 SK8K+S2wWUqQnvyK9uIqYltoKY6I2Ow6Mkk5wLRrBJYcArQeWp+oEQd3Fq1DZwDTwf4G OeajzT3186xeqQesQPsOyBpjsxKBPvJYJ7yGK4ccMDetVJVYzXJMy/qWuWnhle2HLY/q fQbw== X-Gm-Message-State: AOJu0Yyr+a9ndvOIvlW6VR78VeI3njvTUsWpDQo7mcxe2J9cywXarstp 1l15CeqK2gETTcIdXYYSby9GEUffgRDSn5B0IkZvZZ+zYqe5E8SSixkC2H8mS4eOydI5NLJ1b// PrkzPktwHI8lEk4INXR/ZKntw9eqEcdBjiKLj X-Gm-Gg: ASbGncsg9wDWQgk0sg2+12kkv1OfFUsTVUn4yNR+9nrWnqC75EdFZ4j7kX3eNmkuH/S +tSWjQn8nvGHznF9BWQBAaF1uWMIPapEzv2Topb0bhuNeSCnEhz4fL24BDlKE+SlSAfSRye6JkJ YXbxPDc5K8K4ASr8Sge+BtjtjoQePfTkRLrq/h2ltCbaB+3gKsqHRQEqYnOvbnw1AWOZc5b8PC X-Google-Smtp-Source: AGHT+IFUFU66jL2YFfrajbuIEatMDpt3vPgLwmvED7Mg825KqpDFOnGiMZBfrh2b5XCPfWXw8em+TNLsGLyMNZ3ZtUI= X-Received: by 2002:a05:690c:b15:b0:70f:83af:7db1 with SMTP id 00721157ae682-7176ccaa703mr43543297b3.19.1751745211861; Sat, 05 Jul 2025 12:53:31 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <96e5addb-1570-4b4f-9915-c3fc55988f24@app.fastmail.com> In-Reply-To: <96e5addb-1570-4b4f-9915-c3fc55988f24@app.fastmail.com> Date: Sat, 5 Jul 2025 12:53:02 -0700 X-Gm-Features: Ac12FXw3osUYt_iI8KAmFuY25LtEvvzIb9VeAoQIfwVbZgzlKwtsy841QvNy-mA Message-ID: Subject: Re: [PHP-DEV] Re: [RFC] [Discussion] #[\DelayedTargetValidation] attribute To: Rob Landers Cc: internals@lists.php.net Content-Type: multipart/alternative; boundary="000000000000170cf8063933f728" From: daniel.e.scherzer@gmail.com (Daniel Scherzer) --000000000000170cf8063933f728 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Jul 4, 2025 at 4:50=E2=80=AFPM Rob Landers wrot= e: > > On Sun, Jun 22, 2025, at 22:00, Daniel Scherzer wrote: > > On Tue, Jun 17, 2025 at 4:26=E2=80=AFPM Daniel Scherzer < > daniel.e.scherzer@gmail.com> wrote: > > Hi internals, > > I'd like to start the discussion for a new RFC about adding a > `#[\DelayedTargetValidation]` attribute. > > * RFC: https://wiki.php.net/rfc/delayedtargetvalidation_attribute > * Implementation: https://github.com/php/php-src/pull/18817 > > --Daniel > > > > It seems a common point of discussion is the difference in behavior > between internal and userland attributes, so I wanted to clarify a few > things: > > * Userland attributes are always metadata, in part because of the > backwards and forward compatibility that those attributes provide - the > attribute does not need to exist in order to be used, it just needs to > exist (and target the location) when you call > ReflectionAttribute::newInstance() to instantiate > * Internal attributes are a mix between metadata and a way to plug into > the engine. There were already existing ways to plug into the engine (e.g= . > using magic methods or implementing the Countable or ArrayAccess > interfaces) but attributes provided a way to plug into the engine when yo= u > don't just want to add a function override, but rather something else (li= ke > indicating a parameter should be redacted in backtraces with > `#[\SensitiveParameter]`). It would probably be impossible to do that > securely with a userland attribute and userland error handler that manual= ly > redacted things... > * Attributes were designed to have good compatibility - the syntax chosen > for PHP 8.0 was, in prior versions of PHP, used for comments - so any cod= e > with attributes could also work in PHP 7.4, just without the metadata. > Similarly, by not validating userland attributes until they are accessed > with reflection, you can add an attribute that does not exist yet (e.g. i= f > using different versions of a library) with minimal complications. > * Internal attributes are validated at compile time - because they can be= . > Internal attributes tell the engine to do something, and it makes sense (= at > least to me) that if the engine cannot do that thing, there should be an > error without needing to wait for ReflectionAttribute::newInstance() to b= e > called. > > But, the validation of internal attributes at compile time means that the= y > lose the compatibility features of userland attributes, and that is what > this RFC is trying to address. To be clear, I think the difference in > behavior between userland and internal attributes is a) fundamentally bas= ed > on the difference in capabilities (pure metadata vs engine behavior) and = b) > something that should not be changed without significant further > investigation. > > > I don=E2=80=99t think this is quite right. Because non-existent attribute= s can be > used, if you use attributes in your library, you already know to only eve= r, > and I mean only ever, instantiate your own attributes. Attempting to > instantiate someone else=E2=80=99s attributes can result in crashes. This= means any > delayed attributes will most likely never be validated by anything. > > Symfony instantiates arbitrary attributes, https://github.com/symfony/symfony/pull/40307 - and while delayed attributes may not end up being validated, that is a feature, not a bug - the goal is that the validation not be performed at compile time, and so it was either delay to runtime, or not do the validation at all. > > This new `#[\DelayedTargetValidation]` is meant to simplify things, and t= o > partially unify the behavior of the errors - if you are getting any error= s > from internal attributes and want to suppress them at compile time, just > add the new attribute everywhere. > > -Daniel > > > I don=E2=80=99t think this is =E2=80=9Cforward compatibility=E2=80=9D, th= is is completely > disabling the attribute. > > =E2=80=94 Rob > So I guess my use of "forward compatibility" was a bit confusing. This allows a library to be backwards compatible (using PHP 8.6 attribute targets but running on PHP 8.5 without errors) by making the language forward compatible (allowing PHP 8.5 to process 8.6 attribute targets without errors, by delaying those errors). The attribute is not disabled at all though. * If the attribute is used in a place where it would do anything (i.e. there wouldn't be an error about being a bad target) then that attribute is used as normal, and #[\DelayedTargetValidation] does not affect it * If the attribute is used in a place where it would error, then it already cannot do anything, and #[\DelayedTargetValidation] just delays the error - the attribute is already going to be inactive anyway -Daniel --000000000000170cf8063933f728 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Fri, Jul 4, 2025 at 4:50=E2=80=AFPM Ro= b Landers <rob@bottled.codes> wrote:
=

On Sun, Jun 22, 2025, at 22:00, Daniel Scherze= r wrote:
On Tue, Jun 17, 2025 at 4:26=E2=80=AFPM Dani= el Scherzer <daniel.e.scherzer@gmail.com> wrote:
Hi internals,

I&= #39;d like to start the discussion for a new RFC about adding a `#[\Delayed= TargetValidation]` attribute.

=
* Implementation:=C2=A0https://github.com/php/php-src/pull/18817

--Daniel

<= br>
It seems a common point of discussion is the difference in be= havior between internal and userland attributes, so I wanted to clarify a f= ew things:

* Userland attributes are always metada= ta, in part because of the backwards and forward compatibility=C2=A0that th= ose attributes provide - the attribute=C2=A0does not need to exist in order= to be used, it just needs to exist (and target the location) when you call= ReflectionAttribute::newInstance() to instantiate
* Internal att= ributes are a mix between metadata and a way to plug into the engine. There= were already existing ways to plug into the engine (e.g. using magic metho= ds or implementing the Countable or ArrayAccess interfaces) but attributes = provided a way to plug into the engine when you don't just want to add = a function override, but rather something else (like indicating a parameter= should be redacted in backtraces with `#[\SensitiveParameter]`). It would = probably be impossible to do that securely with a userland attribute and us= erland error handler that manually redacted things...
* Attribute= s were designed to have good compatibility - the syntax chosen for PHP 8.0 = was, in prior versions of PHP, used for comments - so any code with attribu= tes could also work in PHP 7.4, just without the metadata. Similarly, by no= t validating userland attributes until they are accessed with reflection, y= ou can add an attribute that does not exist yet (e.g. if using different ve= rsions of a library) with minimal complications.
* Internal attri= butes are validated at compile time - because they can be. Internal attribu= tes tell the engine to do something, and it makes sense (at least to me) th= at if the engine cannot do that thing, there should be an error without nee= ding to wait for ReflectionAttribute::newInstance() to be called.

But, the validation of internal attributes at compile time = means that they lose the compatibility features of userland attributes, and= that is what this RFC is trying to address. To be clear, I think the diffe= rence in behavior between userland and internal attributes is a) fundamenta= lly based on the difference in capabilities (pure metadata vs engine behavi= or) and b) something that should not be changed without significant further= investigation.

I don=E2= =80=99t think this is quite right. Because non-existent attributes can be u= sed, if you use attributes in your library, you already know to only ever, = and I mean only ever, instantiate your own attributes. Attempting to instan= tiate someone else=E2=80=99s attributes can result in crashes. This means a= ny delayed attributes will most likely never be validated by anything.


Symfony instantiates= arbitrary attributes,=C2=A0https://github.com/symfony/symfony/pull/40307 - and while de= layed attributes may not end up being validated, that is a feature, not a b= ug - the goal is that the validation not be performed at compile time, and = so it was either delay to runtime, or not do the validation at all.
=C2=A0
=

This new `#[\DelayedTargetValidation]` is me= ant to simplify things, and to partially unify the behavior of the errors -= if you are getting any errors from internal attributes and want to suppres= s them at compile time, just add the new attribute everywhere.
-Daniel=C2=A0

I don=E2=80=99t think this is =E2=80=9Cforward compatibility=E2=80=9D, th= is is completely disabling the attribute.

=E2=80=94 Rob


So I guess my use of "forward compatib= ility" was a bit confusing. This allows a library to be backwards comp= atible (using PHP 8.6 attribute targets but running on PHP 8.5 without erro= rs) by making the language forward compatible (allowing PHP 8.5 to process = 8.6 attribute targets without errors, by delaying those errors). The attrib= ute is not disabled at all though.

* If the attrib= ute is used in a place where it would do anything (i.e. there wouldn't = be an error about being a bad target) then that attribute is used as normal= , and #[\DelayedTargetValidation] does not affect it
* If the att= ribute is used in a place where it would error, then it already cannot do a= nything, and #[\DelayedTargetValidation] just delays the error - the attrib= ute is already going to be inactive anyway

-Daniel=
=C2=A0
--000000000000170cf8063933f728--