Re: [PHP-DEV] Inconsistencies between parameter number and index when reflecting a method/function

2024-05-03 Thread Ollie Read
On Fri, May 3, 2024, at 1:45 AM, Gina P. Banyard wrote:
> On Thursday, 2 May 2024 at 21:33, Derick Rethans  wrote:
> 
> > On 2 May 2024 13:48:36 BST, Ollie Read php@ollie.codes wrote:
> > 
> > > These methods accept an integer to retrieve a parameter by its position, 
> > > or a string to retrieve by its name. So far, I have built this so that if 
> > > you required the first parameter, it's parameter 0. I treat it this way 
> > > because the only other place where we deal with parameter indexes, is 
> > > ReflectionFunctionAbstract::getParameters() which returns the parameters 
> > > zero-indexed.
> > > 
> > > The question that is holding this PR back is should these methods be 1 
> > > indexed, so that the provided position is consistent with the error 
> > > messages, or how a person would typically count, or should they be 0 
> > > indexed to remain consistent with the existing API.
> > 
> > 
> > 0-indexed, as that's what PHP does everywhere else.
> > 
> > cheers
> > Derick
> 
> Well not really, if you have an error (TypeError or ValueError) which 
> indicate what parameter is the problem, it will be 1-indexed.
> 
> Which, for me, makes it more logical to have it 1-indexed.
> If the ReflectionFunctionAbstract::getParameters() API did not exist, this is 
> what I would have pushed for.
> 
> Moreover, PHP already has a 1-indexed and 0-indexed discrepancy with the 
> ob_get_level() and ob_get_status() functions.
> 
> In the end, I don't really care what we choose, but this just needed 
> clarification from internals on how to proceed.
> 
> Best regards,
> 
> Gina P. Banyard
> 

It looks like the consensus seems to be 0-indexed, but I'm happy to allow it a 
bit more time to get a few more opinions if you'd prefer.

I do totally understand what you're saying, though. I think people are 
typically already capable of differentiation. We know that the first entry in a 
list array, so entry 1, is index 0. Not to mention the way getPosition() and 
getParameters() works.

---
Best Regards,
*Ollie Read*


[PHP-DEV] Inconsistencies between parameter number and index when reflecting a method/function

2024-05-02 Thread Ollie Read
Hi All,

I've been working on a PR that introduces 
ReflectionFunctionAbstract::getParameter() and 
ReflectionFunctionAbstract::hasParameter(), to fall more inline with the other 
method sets we have, as well as just generally making peoples lives easier.

The PR is here: https://github.com/php/php-src/pull/10431

These methods accept an integer to retrieve a parameter by its position, or a 
string to retrieve by its name. So far, I have built this so that if you 
required the first parameter, it's parameter 0. I treat it this way because the 
only other place where we deal with parameter indexes, is 
ReflectionFunctionAbstract::getParameters() which returns the parameters 
zero-indexed.

The question that is holding this PR back is should these methods be 1 indexed, 
so that the provided position is consistent with the error messages, or how a 
person would typically count, or should they be 0 indexed to remain consistent 
with the existing API.

Girgias has asked that I pause the PR until we can have a discussion on this 
mailing list about how to approach it, so I'm looking for feedback on this.


---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] New reflection methods for working with attributes

2023-08-07 Thread Ollie Read

> Please go ahead! Thanks for caring.
> And if you already have the patch ready for hasAttribute() too but just care 
> enough to leave it to the wanna-be-first-time-contributor that I am, please 
> consider sharing it to me so that I can compare with what I have once I’m 
> back from vacation next week (and either come back to you with questions or 
> incline myself :)). Or I’ll send you mine for early review when I’m back to 
> keyboard if you’re ok.

I'll wait for your implementation, as all the methods will be virtually 
identical, so it's best to base it off your hasAttribute method.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] New reflection methods for working with attributes

2023-08-03 Thread Ollie Read

> Alright, I will just ship the PR for `hasAttribute()` then.
> Thanks for the hints and feedback.
> And sorry for the bad posting style, I hope this one is ok.

In that case, are you happy for me to PR the other two methods I suggested, or 
would you like to handle that?

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] New reflection methods for working with attributes

2023-07-25 Thread Ollie Read
> I'm not opposed to these, but would this be a good time to also add an 
> interface for attributable reflection objects, so that we can type against 
> that?  These methods would all then go on that interface.

I was going for a tiered approach. Once these methods were in, I would propose 
adding an Attributable or ReflectorWithAttributes interface, as well as a 
separate proposal to have ReflectionAttribute aware of the 
Attributable/ReflectionWithAttributes that it came from.

> What's the difference between this and what was proposed in
> https://externals.io/message/120799 ? 

My proposal adds 3 methods, not just one, and was a followup to something from 
a while ago.

> I don't get why this wouldn't require an RFC.

It's adding missing methods that should realistically be there. It breaks 
nothing, nor does it introduce entirely brand new things. It's the same as 
getParameter()/hasParameter() <https://github.com/php/php-src/pull/10431> and 
hasPrototype() <https://github.com/php/php-src/pull/8487>. I couldn't tell you 
exactly why, just that the core contributors said so.

> FY  I started working on the implementation., hopefully it will bring more 
> arguments in favor of that RFC which I’m willing to submit asap as well.

Is it just the hasAttribute() method you're working on? I'm happy to help out 
if you need/want it. I was moments away from opening a PR.

---
Best Regards,
*Ollie Read*


[PHP-DEV] New reflection methods for working with attributes

2023-07-25 Thread Ollie Read
Hello all,

A while back, I wrote a lengthy post about suggested improvements for 
reflection, but I would like to come back to address additional methods for 
dealing with attributes. (I have an open git issue here: 
https://github.com/php/php-src/issues/8489)

I'd like to introduce the following three methods on all reflect classes that 
have attributes:

hasAttribute(string $name, int $flags = 0): bool

Uses the same filtering as getAttributes(), but returns true if a match is 
found, false otherwise.

getAttribute(string $name, int $flags = 0): ?ReflectionAttribute

Also uses the same filtering as getAttributes(), except that it will return an 
instance of ReflectionAttribute if one is found, null if none are found, and 
will throw an exception of more than 1 is found.

getNumberOfAttributes(?string $name = null, int $flags = 0): int

Again, uses the same filtering as getAttributes(), and is to attributes what 
getNumberOfParameters() is to parameters. I appreciate that this methods use 
may not be obvious, but I wanted to include it for consistency.

I'm relatively confident that I have worked out the best method of implementing 
these, and contributors have agreed to merge a PR, which I will start shortly, 
should there be no objections.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically

2023-01-24 Thread Ollie Read
You're absolutely correct, the problem I was trying to solve was the ability to 
reference a method without throwing around magic strings, apologies if that 
wasn't clear.

The whole idea, or rather, need/want for it came about because of time spent 
with Javas functional side, though I understand that's safer to do because of 
the way Java handles type safety.

The ::class pseudo type is great for providing a classes FQN, and class-string 
is great for ensuring values are valid class strings when using static 
analysis, but we don't have anything for methods, outside of IDE completion.

The solution wouldn't even need to generate a closure, TBH, it would generate 
something that could then be used in the same manner.

Using the current features of PHP, I'd probably imagine something that does 
just about the same as this:

$method = new ReflectionMethod(MyClass::class, 'method');

$collection->filter($method);

Where the filter method does:

foreach ($items as $item) {
if ($method->invoke($item)) {
//
}
}

Although reflection doesn't have the overhead that everyone thinks it does, 
this is a less than ideal solution, but I think it accurately portrays what I'm 
looking for.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically

2023-01-23 Thread Ollie Read
There's definitely similarity, but I would say it sits somewhere between the 
two. Rather than reference a partial method call, or create a closure for a 
method, you're delaying a method call. Or rather, referencing a method. We have 
the ::class pseudo property, so I see this like an equivalent, but for methods.

On Mon, Jan 23, 2023, at 4:50 PM, Deleu wrote:
> 
> 
> On Mon, Jan 23, 2023, 1:16 PM Ollie Read  wrote:
>> Oh, I didn't mean to suggest that it automatically binds.
>> 
>> My second suggestion for how to achieve this does require some sort of 
>> automation. If you create a closure from Str::someMethod($arg1, $arg2) where 
>> someMethod isn't static, it should create a closure with the signature 
>> fn(Str $object, $arg1, $arg2), which would wrap a call to [$object, 
>> 'someMethod]($arg1, $arg2).
> 
> I think this starts to wonders in the realm of Partial Function Application 
> https://wiki.php.net/rfc/partial_function_application
> 

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically

2023-01-23 Thread Ollie Read
Oh, I didn't mean to suggest that it automatically binds.

My second suggestion for how to achieve this does require some sort of 
automation. If you create a closure from Str::someMethod($arg1, $arg2) where 
someMethod isn't static, it should create a closure with the signature fn(Str 
$object, $arg1, $arg2), which would wrap a call to [$object, 
'someMethod]($arg1, $arg2).

However, perhaps the simplest solution, and one that could be done realtively 
easily and quickly, would be to delay the error, and allow static closures to 
bound with Closure::bind() if they represent a non-static method.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically

2023-01-23 Thread Ollie Read
You are absolutely correct. I guess the solution would be to handle it 
differently in this case.

Creating a closure from a static method would be fine, as it creates a static 
closure, but when attempting to create a static closure from a non-static 
method, it would instead return a closure that errors if it isn't bound to an 
appropriate object. You'd most likely want to restrict this to public methods 
only, which would help with the security issues.

There's already a check there that throws an error, so we can already tell the 
difference there, but the tricky part will be in the returned closure. Perhaps 
something like "BindingClosure" that throws the static error when attempting to 
call it unbound, or better yet, a more descriptive error about it requiring 
binding.

Would that be feasible?

On Sun, Jan 22, 2023, at 8:36 PM, Larry Garfield wrote:
> On Sun, Jan 22, 2023, at 11:45 AM, Ollie Read wrote:
> > Hello all,
> >
> > I've created a feature request issue on GitHub (here: 
> > https://github.com/php/php-src/issues/10414), but I have been advised 
> > that it's best to post here.
> >
> > What I would like to introduce/suggest, is the ability to create a 
> > closure from a method using the first-class-callable syntax (eg: 
> > MyClass::aMethod(...)), for a non-static method, statically. 
> >
> > Currently, the following code causes an error.
> >
> > ```
> > class Test {
> > public function test(): string { return 'test'; }
> > }
> > 
> > $closure = Test::test(...);
> > ```
> >
> > I understand why the error is thrown, but, and I'm unsure of the 
> > specifics regarding this, I think we could delay the error until the 
> > closure was called. The reason for this, is that closures can be bound, 
> > so if you followed on from the code above, you could do the following:
> >
> > ```
> > $closure->bindTo(new Test);
> > $closure();
> > ```
> >
> > The above would bind the closure in $closure to the scope of an object, 
> > which in this case, is the class that the method belongs to.
> >
> > The best example I can think, for this, would be when filter a 
> > collection of instances. If you were using a collection library, you 
> > would currently have something like the following:
> >
> > ```
> > $collection->filter(function (Str $string) {
> > return !$string->empty();
> > });
> > ```
> >
> > Whereas it would be much nicer to have the following:
> >
> > ```
> > $collection->filter(Str::empty(...));
> > ```
> >
> > In this situation, the collection library would be responsible for 
> > binding the closure to the value it is iterating.
> 
> So you'd implement this yourself elsewhere?
> 
> class Str {
>   public function empty(): bool { ... }
> }
> 
> I don't see in this example how this is any better than what is already 
> currently possible:
> 
> class Str {
>   public static function empty(Str $s): bool { ... }
> }
> 
> $collection->filter(Str::empty(...));
> 
> > I have limited experience with PHPs source, and C in general, but my 
> > understanding would be that if we were creating a closure, we would 
> > skip the check for the static method. The code responsible for handling 
> > the closure call would most require some additional functionality to 
> > check if it was bound to a valid instance, returning an error if it 
> > isn't, and then returning an error if it isn't bound at all and the 
> > method isn't static.
> >
> > The more I think about it, the more I think this may require a new type 
> > of Closure, or at least a runtime applied interface, to help developers 
> > determine whether a closure was created using first-class-callable 
> > syntax.
> 
> This is, I think, the important part here, and would be a prerequisite.  
> Right now there's no way (as far as I know) to differentiate a closure that 
> is callable from one that would be callable if it were bound to an object.  
> That's generally not a huge deal in practice as unbound closures are not 
> often used, but what you're suggesting would make them much more likely.  
> Also, a static closure cannot be bound, so you cannot just blindly bind 
> whatever callable you're passed to $this, in your example.  (Besides, blindly 
> binding a closure to $this sounds like a great security hole.)
> 
> So for some variant of this to work, I think you'd first need to think 
> through how to (easily and without dipping into reflection) determine if a 
> closure object is bindable (static or not) and if it's already bound.  Once 
> that's figured out, then we can see what, if any, short-hand way to make a 
> not-yet-bound closure makes sense.  (Which could be FCC syntax or not, I 
> don't know.)
> 
> --Larry Garfield
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 
> 

---
Best Regards,
*Ollie Read*


[PHP-DEV] Introduce the abiltiy to use the first-call-callable syntax on non-static methods, statically

2023-01-22 Thread Ollie Read
Hello all,

I've created a feature request issue on GitHub (here: 
https://github.com/php/php-src/issues/10414), but I have been advised that it's 
best to post here.

What I would like to introduce/suggest, is the ability to create a closure from 
a method using the first-class-callable syntax (eg: MyClass::aMethod(...)), for 
a non-static method, statically. 

Currently, the following code causes an error.

```
class Test {
public function test(): string { return 'test'; }
}
 
$closure = Test::test(...);
```

I understand why the error is thrown, but, and I'm unsure of the specifics 
regarding this, I think we could delay the error until the closure was called. 
The reason for this, is that closures can be bound, so if you followed on from 
the code above, you could do the following:

```
$closure->bindTo(new Test);
$closure();
```

The above would bind the closure in $closure to the scope of an object, which 
in this case, is the class that the method belongs to.

The best example I can think, for this, would be when filter a collection of 
instances. If you were using a collection library, you would currently have 
something like the following:

```
$collection->filter(function (Str $string) {
return !$string->empty();
});
```

Whereas it would be much nicer to have the following:

```
$collection->filter(Str::empty(...));
```

In this situation, the collection library would be responsible for binding the 
closure to the value it is iterating.

I have limited experience with PHPs source, and C in general, but my 
understanding would be that if we were creating a closure, we would skip the 
check for the static method. The code responsible for handling the closure call 
would most require some additional functionality to check if it was bound to a 
valid instance, returning an error if it isn't, and then returning an error if 
it isn't bound at all and the method isn't static.

The more I think about it, the more I think this may require a new type of 
Closure, or at least a runtime applied interface, to help developers determine 
whether a closure was created using first-class-callable syntax.

I'm interested in feedback on this, and if anyone could point me towards the 
correct part of the codebase that handles this, I can investigate further. I am 
happy to create an RFC if others think this viable.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-08 Thread Ollie Read
On Mon, Aug 8, 2022, at 3:54 AM, Mike Schinkel wrote:
> 3.) I have concerns about the proposed methods isProtectedSet() and 
> isPrivateSet().  
> 
> These names feels like we are asking if some thing "Set" is "Protected" or 
> "Private" where no such "thing" exists in this context.  
> 
> In other words it reads as if you are asking "Is it a *protected* Set?" or 
> "Is it a *private* Set?"  Such naming also does not relate to the Property 
> itself which is what the prefix verb "is" is acting on.
> 
> I would propose instead we consider the following are these instead would be 
> asking the *ability* to "Set" the Property is "Protected" or "Private" where 
> The Property is again what the prefix verb "is" is acting on:
> 
> isSetProtected()
> isSetPrivate()
> isGetProtected(), and
> isGetPrivate()

I feel almost as if we shouldn't pollute ReflectionProperty with these 
additional methods but should instead have something like 
ReflectionAsymmetricProperty, which would in turn extend ReflectionProperty. 

I guess it depends on how it's handled. If all property handling is updated so 
that "public int $number" is identical to "public:get public:set int $number", 
there's no issue, but if we treat those with separate visibilities to be 
additional, it probably makes sense to be somewhat separate.

While isGetProtected() is technically false for "public int $number", if it's 
not inferred, it's semantically incorrect. A good example of this is 
ReflectionMethod::getPrototype, which throws an exception if there's no 
prototype. Although this is somewhat bizarre, it is at least a thing we do.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] [RFC] Asymmetric visibility

2022-08-07 Thread Ollie Read
On Sun, Aug 7, 2022, at 9:38 PM, Rowan Tommins wrote:
> On 07/08/2022 11:54, Lynn wrote:
> > Reading "public private", "public protected", or "protected private" 
> > reads really weird `public private(set) static self $property`.
> 
> 
> Interesting, it seems that you've unconsciously broken it up as "public 
> private" followed by "(set)", rather than "public" followed by 
> "private(set)". Perhaps it's because of the position of the parentheses, 
> which do feel awkward to me at first glance. Would it read more 
> naturally to you with different punctuation?
> 
> public (private set) static self $property;
> 
> Or:
> 
> (public; private set) static self $property;
> 
> Or:
> 
> public private-set static self $property;
> 
> 
> 
> On 05/08/2022 19:08, Matthew Weier O'Phinney wrote:
> > I'm wondering if this sort of behavior could be indicated via attributes
> > instead? Something like `#[PropertySetBehavior(PROPERTY_SET_PRIVATE)]`.
> > Attributes have the benefit of being separate from the property
> > declaration, arguably more readable (one per line), and composable.
> 
> 
> Attributes are no more intrinsically "separate" or "one per line" than 
> keywords; the following would be perfectly valid with the RFC's proposed 
> syntax:
> 
> class Foo {
>public private(set)
>static int|string $id;
> }
> 
> And the following would be valid with an attribute like you suggest:
> 
> class Foo {
>#[PropertySetBehavior(PROPERTY_SET_PRIVATE)] public static 
> int|string $id;
> }
> 
> Even a shorter attribute name would have the extra punctuation, and the 
> restriction that it comes before the normal visibility keyword:
> 
> class Foo {
>#[PrivateSet] public static int|string $id;
> }
> 
> 
> Regards,
> 
> -- 
> Rowan Tommins
> [IMSoP]
> 
> -- 
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: https://www.php.net/unsub.php
> 
> 

Just to throw in my ten cents:

I'm not sure if this is because I was recently reading about the fact that PHP 
doesn't have proper support for a comma operator, but I quite like the idea of 
providing them as a comma-separated list.

// Public for get and set
public int $number

// Public get, private set
public, private int $number

If a single visibility is provided, same old same old, but if two are provided, 
they are in the order of get, followed by set. While not being as verbose as 
providing (set) or other markings to differentiate them, it feels more natural, 
and it doesn't overcomplicate it.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] RFC Idea: Introducing a ReflectionWithAttributes interface - Looking for feedback

2022-08-07 Thread Ollie Read

On Sun, Aug 7, 2022, at 7:56 PM, Larry Garfield wrote:
> So I'm all for adding a proper interface here.  However, I am unclear why it 
> needs to be separate from Reflector.  Reflector is already used by all the 
> same classes that can have attributes, no?  Wouldn't just adding the 
> attribute methods to that interface be sufficient?

Sadly the Reflector interface is implemented by ReflectionExtension, which does 
not support attributes. It's also because adding those methods to Reflector now 
prevents any future implementation of that method for something that doesn't 
have attributes. Keep it simple, keep it separate.

> I'm mixed on the new methods.  The current equivalent of getAttribute() is:
> 
> $r->getAttributes($attrClass, \ReflectionAttribute::IS_INSTANCEOF)[0] ?? null;
> 
> Which I don't mind.  My main concern there would be how it interacts with 
> repeating/non-repeating attributes.  Can you call getAttribute() on a 
> repeating attribute?  Can you call getAttributes() on a non-repeating? Do 
> they behave any differently?  There's likely answers to these questions, but 
> they would need to be asked.

The methods would behave the same in terms of how it retrieves and returns the 
results, with the exception that getAttribute will only return one attribute or 
null. The main idea I have is that calling getAttribute for an attribute that 
is present more than once should throw an exception. 

> Would hasAttribute() and getNumberOfAttributes() have any performance benefit 
> over calling count() on getAttributes()?  Again, this isn't a pain point I've 
> had with attributes yet.  If so, I'd combine them into an attributeCount() 
> method that returns an int, and if it returns 0 you know it wasn't defined.

I'm afraid I couldn't say for certain, though it's highly likely that any 
performance increase would be negligible and not worth worrying about. I 
appreciate that they are easy to do in userland, but the same could be said for 
ReflectionFunctionAbstract::getNumberOfParameters and 
ReflectionClass::hasMethod.

The idea behind these two is to provide a nice API with sensible actions, while 
trying to maintain consistency, something we sorely need in the core.

I think the cost of having these methods is nothing compared to the nicer 
interface and API provided by having them as part of an interface.

---
Best Regards,
*Ollie Read*


Re: [PHP-DEV] Re: RFC Idea - is_json - looking for feedback

2022-08-07 Thread Ollie Read
Hey,

While I'm not opposed to the idea, I'm struggling to think of a way to 
accurately determine whether a string is true JSON that doesn't involve some 
sort of parsing.

Sure some regexes can be run on it, but I'm not sure that will ever be 100% 
accurate. Any parsing of the JSON to determine whether or not it's valid JSON 
would, in most situations, lead down a code path that then parsed the JSON 
again, essentially repeating the same function for little benefit.

I personally like to use the *`JSON_THROW_ON_ERROR`* flag on json_decode.

Not trying to rain on your parade, so sorry if it comes across that way, I'm 
just not sure of a way to do it where the benefit outweighs the cons, but then 
again, there are people a lot smarter than me on this list.

---
Best Regards,
*Ollie Read*


[PHP-DEV] RFC Idea: Introducing a ReflectionWithAttributes interface - Looking for feedback

2022-08-07 Thread Ollie Read
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*



Re: [PHP-DEV] Possible improvements to the Reflection functionality

2022-05-07 Thread Ollie Read
Hey again!
> Greetings.
> 
> I've also been doing a lot of work with Reflection lately as part of 
> https://github.com/Crell/AttributeUtils .  I agree with and support almost 
> all of these additions.  (I'm no entirely convinced by 
> getNumberOfAttributes(), but I don't really see a harm in it.)

Yeah, the idea behind getNumberOfAttributes was merely because it doesn't hurt 
to have, and since we're dealing with having 1 or more of a particular type of 
attribute, there are absolutely going to be times when has and get won't cut it.

> There was another short thread on the list back in February?, I think, about 
> some improvements to reflection.  We desperately need a few more well-placed 
> interfaces and stubs for things like attributes, and even getName().  My C-fu 
> is paltry if I'm being polite, but I'm happy to help with process and RFC 
> writing/documentation.  The Reflection API is badly in need of some love.

I'm super new to the list, in fact, this was my first interaction with it at 
all. My C-fu is practically non-existent, in fact, the first thing I ever did 
with C in my entire life, was the PR to fix the bug with closure attributes. 
That being said, I'm fairly confident that I have a decent understanding of how 
the reflection parts of the codebase work, and I've spent enough time poking 
around it that I think I know how to do most of what I have suggested.

> In practice, I think most of these would require RFCs.  The question is 
> whether they're better as a bunch of stand-alone RFCs or one big "clean up 
> Reflection" RFC or a series of "clustered" RFCs.  I'm not sure what's most 
> palatable to folks these days.

That's a good point. I'd be inclined to, at the very least, create two RFCs, 
one for types, and one for attributes, as while they both use reflection, 
they're very different points that are only connected in that they're part of 
reflection.

Since posting the original list, I even came up with an idea to expand on the 
typing, and introduce actual classes for each of the "types" (perhaps an enum), 
that the reflection types can use. I think that would be super useful for a lot 
of stuff, all the way from dependency injection to static analysis. Something 
like https://docs.microsoft.com/en-us/dotnet/api/system.type?view=net-6.0, but 
we could probably just make the reflection classes use that.

I'd also like to see the Reflection prefix dropped and proper namespacing 
introduced, but I also know that's not going to go down well with a lot of 
people.

Am happy to hear any suggestions or input, especially how people feel about the 
whole RFC side of things.

---
Best Regards,
*Ollie Read*


[PHP-DEV] Possible improvements to the Reflection functionality

2022-05-05 Thread Ollie Read
Hello all,

I've been spending a lot of time in the world of PHP reflection lately, which 
has led me to create PRs for the documentation, a bug for closure attributes, 
and even a new method on ReflectionMethod. I've also compiled a list of 
suggestions for various additions and improvements to some parts of reflection. 

You can find it here: 
https://gist.github.com/ollieread/34c878bf120ee70f9d2a869cb7a242d1

I'm looking for some feedback on the various elements and some guidance, if any 
have merit, as to whether they're going to require any sort of RFC. I'm also 
happy to create PRs for some of the features, if not all, though I think there 
are definitely some beyond my current knowledge. I would also be interested in 
hearing from anyone who also has other suggestions that could be added to this.

Apologies if I'm missing something, or I could have done something better, this 
is my first interaction with this mailing list, so I am also happy to receive 
any feedback about the best approaches and ways to handle things, if necessary.

---
Best Regards,
*Ollie Read*