Hello all,

A while back, I posted on this mailing list with a link to a gist that had a 
brain dump proposal for improvement to reflection essentially, but I'd like to 
start again by including more detail here and by breaking it up.

The current implementation of attributes with PHP is great, but it feels like 
it's lacking a bit. What I'd like to do is introduce 3 new methods that fall 
more in line with the way that other child elements are handled within 
reflection and then introduce an interface called ReflectionWithAttributes, 
which can be implemented by all Reflector implementations that have attributes.

I would like to put all of this in an RFC and would be more than happy to have 
a go at doing the work, too, should it be something people are interested in, 
but I wanted to put it on here first to get some feedback, so here's the 
breakdown/my thinking.

## The Interface
Attributes are unlike most other parts of reflection in that their usage and 
effect on a codebase or application are entirely arbitrary. Because of this, a 
lot of applications and packages will likely have handlers and wrappings around 
the reflection of attributes, and having a "ReflectionWithAttributes" interface 
would allow developers to handle this without having to create rather 
annoyingly long union types for all the reflection classes that have attributes.

As far as I can tell, the introduction of this interface would not be a 
disruption in the slightest, so there's no real downside to doing so.

## The Methods
There are several methods that developers could benefit from with the above 
interface.

### getAttributeTarget
Of all the methods, this is the one I'm most uncertain about, but the idea is 
simple. ReflectionWithAttribute::getAttributeTarget returns the corresponding 
constant in Attribute that is relevant to the current implementation. So 
ReflectionClass::getAttributeTarget would return Attribute::TARGET_CLASS.

The idea behind this is that a developer can accept the type 
ReflectionWithAttribute, and won't have to do any instanceof checks to figure 
out what sort of attributes they're dealing with in a situation where that's 
important before retrieving the actual attributes.

I'm relatively certain this would be trivial to implement, as the 
implementation will know what it is.

### getAttribute
There is currently a way to retrieve all of the attributes, but not just one. 
There are ways to do this in userland, but I'd wager that a good percentage of 
the time, there's only one attribute there.

The idea behind this method is to bring this more inline with other parts of 
reflection, where the other methods have singular versions to, ie, getMethods, 
getMethod, getProperties, getProperty, etc, etc.

Again, I suspect the implementation of this would be trivial, as it could 
essentially wrap getAttributes but just return the first item, as it would have 
an identical signature, except for the singular return type or null. There's 
also the option of throwing an exception if there's more than one match to 
avoid unforeseen side effects.

### hasAttribute
This method is again an attempt to bring attributes more inline with the rest 
of reflection, as we have hasMethod, hasProperty, etc.

Much like getAttribute, this method would have an identical signature to 
getAttributes, but would return a bool instead. Again, this could just wrap 
getAttributes returning that its size is greater than 0.

### getNumberOfAttributes
For all intents and purposes, this method is identical to hasAttribute except 
that it returns the actual size from getAttributes. In fact, hasAttribute could 
probably wrap this. The idea behind this method is to mirror the 
ReflectionFunctionAbstract::getNumberOfParameters method.

Like the others, its signature would be the same, except that it returns an 
int. 

## Conclusion
Would love to hear any thoughts on this, I know that a few developers that I 
have spoken to outside of this are fond of the idea, and as far as I can tell, 
the implementation wouldn't be too difficult, and shouldn't cause any 
disruptions at all. And as I said, I'm more than happy to take on the task of 
implementing this, rather than expect someone else to do it.

If you're interested, the brain dump gist is here: 
https://gist.github.com/ollieread/34c878bf120ee70f9d2a869cb7a242d1#attributes

---
Best Regards,
*Ollie Read*

Reply via email to