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
Hi internals,
I’d like to start the discussion for a new RFC about adding a #[\DelayedTargetValidation]
attribute.
–Daniel
On Wed, Jun 18, 2025, at 01:26, Daniel Scherzer 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
Interesting. I’d also argue for the inverse more than this, though. I’d like for my attributes to be validated during compilation instead of delayed to runtime – which, it isn’t actually. Runtime validation ONLY happens when calling ->newInstance() on ReflectionAttribute, and never before then. So, only when an attribute is actually read during reflection is it validated. Further, if you never actually instantiate it … it is never actually validated (i.e., just looking for the presence of an attribute, not the details).
— Rob
Von meinem iPhone gesendet
Am 18.06.2025 um 11:26 schrieb Rob Landers rob@bottled.codes:
On Wed, Jun 18, 2025, at 01:26, Daniel Scherzer 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
Interesting. I’d also argue for the inverse more than this, though. I’d like for my attributes to be validated during compilation instead of delayed to runtime – which, it isn’t actually. Runtime validation ONLY happens when calling ->newInstance() on ReflectionAttribute, and never before then. So, only when an attribute is actually read during reflection is it validated. Further, if you never actually instantiate it … it is never actually validated (i.e., just looking for the presence of an attribute, not the details).
As Daniel’s rfc mentions you need to differentiate between compiler and userland attributes.
The compiler attributes are validated at compile time not dueing newInstance.
— Rob
On 18 June 2025 13:09:26 CEST, kontakt@beberlei.de wrote:
Von meinem iPhone gesendet
Am 18.06.2025 um 11:26 schrieb Rob Landers <rob@bottled.codes>:
On Wed, Jun 18, 2025, at 01:26, Daniel Scherzer wrote:
Hi internals,I'd like to start the discussion for a new RFC about adding a `#[\DelayedTargetValidation]` attribute.
* RFC: PHP: rfc:delayedtargetvalidation_attribute
* Implementation: Add `#[\DelayedTargetValidation]` attribute by DanielEScherzer · Pull Request #18817 · php/php-src · GitHub--Daniel
Interesting. I’d also argue for the inverse more than this, though. I’d like for my attributes to be validated during compilation instead of delayed to runtime -- which, it isn’t actually. Runtime validation ONLY happens when calling ->newInstance() on ReflectionAttribute, and never before then. So, only when an attribute is actually read during reflection is it validated. Further, if you never actually instantiate it ... it is never actually validated (i.e., just looking for the presence of an attribute, not the details).
As Daniel’s rfc mentions you need to differentiate between compiler and userland attributes.
The compiler attributes are validated at compile time not dueing newInstance.
— Rob
Just as an information:
We are at the moment in the proces of setting up a registry for userland attributes at the PHP-FIG.
For more information regarding that check out <https://github.com/php-fig/fig-standards/pull/1331>
Cheers
Andreas
--
Andreas Heigl
On Wed, Jun 18, 2025, at 13:09, kontakt@beberlei.de wrote:
Von meinem iPhone gesendet
Am 18.06.2025 um 11:26 schrieb Rob Landers rob@bottled.codes:
On Wed, Jun 18, 2025, at 01:26, Daniel Scherzer 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
Interesting. I’d also argue for the inverse more than this, though. I’d like for my attributes to be validated during compilation instead of delayed to runtime – which, it isn’t actually. Runtime validation ONLY happens when calling ->newInstance() on ReflectionAttribute, and never before then. So, only when an attribute is actually read during reflection is it validated. Further, if you never actually instantiate it … it is never actually validated (i.e., just looking for the presence of an attribute, not the details).
As Daniel’s rfc mentions you need to differentiate between compiler and userland attributes.
The compiler attributes are validated at compile time not dueing newInstance.
— Rob
Yes, but when would it check it during runtime? It doesn’t say in the RFC. From what I can tell, it effectively disables the attribute, unless someone happens to enumerate and instantiate all the attributes (which is unlikely).
— Rob
Hi Daniel,
While I’m in favor of the RFC, I’d more like to see the default behavior of internal and userland attributes adjusted to work the same, with both having delayed validation enabled by default. Treating core attributes differently doesn’t make sense to me.
So, if that’s someone you’re willing to work on, I’d very much prefer that.
But if there are downsides to this approach or if this is too complicated for other reasons, this attribute is a net positive in my book to make forward compatibility possible.
One note on the example code:
class Base {
class Child extends Parent {
\
Parent isn’t a valid class name, and I think you wanted to extend from Base here? I’d prefer the example to compile so that they can be used for documentation later on where possible.
Kind Regards,
Volker
Volker Dusch
Head of Engineering
Tideways GmbH
Königswinterer Str. 116
53227 Bonn
https://tideways.io/imprint
Sitz der Gesellschaft: Bonn
Geschäftsführer: Benjamin Außenhofer (geb. Eberlei)
Registergericht: Amtsgericht Bonn, HRB 22127
On Wed, Jun 18, 2025 at 5:22 AM Volker Dusch <volker@tideways-gmbh.com> wrote:
On Wed, Jun 18, 2025 at 1:28 AM Daniel Scherzer <daniel.e.scherzer@gmail.com> wrote:
I’d like to start the discussion for a new RFC about adding a
#[\DelayedTargetValidation]
attribute.Hi Daniel,
One note on the example code:
class Base {
class Child extends Parent {
\Parent isn’t a valid class name, and I think you wanted to extend from Base here? I’d prefer the example to compile so that they can be used for documentation later on where possible.
Kind Regards,
Volker
Fixed, thanks.
Hi Volker
On Wed, Jun 18, 2025 at 2:23 PM Volker Dusch <volker@tideways-gmbh.com> wrote:
On Wed, Jun 18, 2025 at 1:28 AM Daniel Scherzer <daniel.e.scherzer@gmail.com> wrote:
I'd like to start the discussion for a new RFC about adding a `#[\DelayedTargetValidation]` attribute.
* RFC: PHP: rfc:delayedtargetvalidation_attribute
* Implementation: Add `#[\DelayedTargetValidation]` attribute by DanielEScherzer · Pull Request #18817 · php/php-src · GitHubWhile I'm in favor of the RFC, I'd more like to see the default behavior of internal and userland attributes adjusted to work the same, with both having delayed validation enabled by default. Treating core attributes differently doesn't make sense to me.
So, if that's someone you're willing to work on, I'd very much prefer that.
I wouldn't support that, because internal attributes with effects are
not usually instantiated.
class C {
#[\SensitiveParameter] // This doesn't actually do anything, only
works on parameters
public $prop;
}
I would get no indication that this attribute doesn't behave as I
expect. We have at least a few attributes with confusable targets
(SensitiveParameter, Override, Deprecated, NoDiscard). User attributes
can't have effects without at least reading them through reflection,
although granted they don't necessarily need to be instantiated, and
so might also not trigger the error.
Ilija
Le mer. 18 juin 2025 à 23:49, Ilija Tovilo <tovilo.ilija@gmail.com> a écrit :
Hi Volker
On Wed, Jun 18, 2025 at 2:23 PM Volker Dusch <volker@tideways-gmbh.com> wrote:
On Wed, Jun 18, 2025 at 1:28 AM Daniel Scherzer <daniel.e.scherzer@gmail.com> wrote:
I’d like to start the discussion for a new RFC about adding a
#[\DelayedTargetValidation]
attribute.While I’m in favor of the RFC, I’d more like to see the default behavior of internal and userland attributes adjusted to work the same, with both having delayed validation enabled by default. Treating core attributes differently doesn’t make sense to me.
So, if that’s someone you’re willing to work on, I’d very much prefer that.
I 100% agree with what Volker posted here.
I wouldn’t support that, because internal attributes with effects are
not usually instantiated.class C {
#[\SensitiveParameter] // This doesn’t actually do anything, only
works on parameters
public $prop;
}I would get no indication that this attribute doesn’t behave as I
expect. We have at least a few attributes with confusable targets
(SensitiveParameter, Override, Deprecated, NoDiscard). User attributes
can’t have effects without at least reading them through reflection,
although granted they don’t necessarily need to be instantiated, and
so might also not trigger the error.
These considerations work exactly the same for userland attributes: if I use #[Whatever] on a location that is not allowed by the declaration of the attribute, nothing will ever tell me at runtime, because nobody will ever try to read that attribute on that unexpected location.
Yet, this “silent” behavior is by design, because that’s the core of the “attributes are declarative metadata” promise. If you make them be enforced by the engine, then this promise falls apart and attributes become way less useful.
The correct solution to the validation problem is to use a static analyzer. There, one can easily spot that some attributes are not correctly placed, and one can then also ignore the report of the SA tool, because eg #[Deprecated] is used on a class on purpose for that library (e.g. for the forward compat use case).
The exception to the declarative nature of attributes that is currently allowed for engine-provided ones is detrimental to me: it allows turning them into “syntax hacks” basically (=engine-enforced-thus-not-declarative rules).
To paraphrase Volker, I’m in favor of the RFC, but only if we cannot agree on the need for internal and userland attributes to have the same conceptual roots (truly declarative ones).
Cheers,
Nicolas
On Tue, Jun 17, 2025 at 4:26 PM 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:
#[\SensitiveParameter]
). It would probably be impossible to do that securely with a userland attribute and userland error handler that manually redacted things…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 difference in behavior between userland and internal attributes is a) fundamentally based on the difference in capabilities (pure metadata vs engine behavior) and b) something that should not be changed without significant further investigation.
This new #[\DelayedTargetValidation]
is meant to simplify things, and to partially unify the behavior of the errors - if you are getting any errors from internal attributes and want to suppress them at compile time, just add the new attribute everywhere.
-Daniel
Hi Daniel, internals,
On Wed, Jun 18, 2025, 02:29 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.
How about completely disabling errors caused by a bad target at compile time?
And just ignore the attribute, that can be validated at runtime if needed.
IDEs and static code analysis would show the problem and that might be enough.
–
Alex