Sorry for the delay here, been quite busy with other work related tasks.

> Frankly I don't like the existence of these 3 functions in SPL.
> This is very much in Reflection territory, and it should only ever be in 
> Reflection.
> SPL is already a mess of badly designed "features" trying to cohabitate.
> The Reflection extension is designed to give you access to do introspection 
> with a well-defined API.

I don't necessarily disagree with this, especially about SPL in
general; however we are at a point where we have them currently (and
the functions are not deprecated/warned against use/etc). That said, I
certainly wouldn't be suggesting adding the function if it didn't
already exist.

> But more over I don't even think you addition makes that much sense.
> Traits are not part of the inheritance hierarchy, that's because the 
> "composition" of traits is effectively just copy and paste.
> Interfaces are fully inherited onto any child class, so there is no need to 
> iterate through the parents to gather all interfaces.
> Traits do not work this way, any "prior" use information is not transmitted 
> due to the copy and paste nature of them.

Note with this, the same constraints apply to parent classes in terms
of the information stored in C - and `ReflectionClass` will return
only the parent as opposed to grandparents/etc; but `class_parents`
returns the parent class / grandparent class / etc. I think this is
the strongest argument for making such a change to `class_uses` -
currently it is inconsistent with the other SPL functions (and I
wouldn't say that modifying the function is going to cause millions of
developers to start using the function, it is more about making the
behaviour a little more consistent).

> The current API doesn't even tell you if used traits also use other traits.
As per your example, `ReflectionClass::getTraits` also does not tell
you about any traits used by other traits, you need to query the
ReflectionClass for the trait returned by 'getTraits'. `class_uses`
will also accept a trait for `$object_or_class`, returning the traits
that trait uses. I would suggest that if a change was made to
class_uses to support optionally returning inherited traits then it
returning traits used on traits or the parent class would make sense.

> I don't even know how it handles trait aliases, or if it even cares about 
> them.
> And that's not even going through overridden trait methods/props/constants at 
> any stage of the inheritance chain.
`class_uses` seems to just return the names of the traits (mirroring
`getTraitNames` on `ReflectionClass` as far as I can tell).

> So I'm very much not convinced about this, nor do I see really the utility of 
> wanting this information?
> But anyway here is a small snippet that will fetch all used traits: 
> https://3v4l.org/kvQGR
In a private / tightly controlled codebase we are using a set of
traits to implement certain functionality at a higher level in the
inheritance chain; and then where needed checking for the existence of
the trait to tell if the functionality is supported or not (think
along the lines of if a trait could implement an interface). There are
various reasons why it isn't easily possible to use interfaces
directly on the relevant classes themselves in the particular codebase
(mainly related to refactoring work required as opposed to technical
reasons) - currently we have gone with a reduced version of the
example code (as we only need to know the names of traits implemented
by the classes as opposed to from traits using traits for our exact
use-case).

(As a quick side note, what I am really looking for proposal 2 from
https://wiki.php.net/rfc/traits-with-interfaces (or a form of `trait`
that does this) and then using traits with interfaces for composition,
however from what I can see on activity such as GH-11435 technical
reasons mean this isn't likely to proceed).

----
I guess the important questions is that regardless of the people's
thoughts on the functions themselves, what are the
benefits/disadvantages of making the change to the pre-existing
function (and if there are more benefits compared to disadvantages, do
those benefits justify introducing the change)? The example code
proves that the information can be gained from userland code; but the
code isn't a straight forward example - and I suspect it is a lot
slower (however you are not likely to do a large number of calls to
the userland or internals code). I still think personally is the
biggest benefit is it brings the behaviour of the three `class_XXXX`
functions in SPL fully inline with each other (that they all return
the parents/interfaces/traits that the class or any related
classes/traits use); and I am not seeing any disadvantages except that
the change not necessary (but I don't think any implementation would
be complex or hard to maintain - my thoughts here would it would
basically be the `while` in `php_spl.c` lines 125-128 (in
`class_parents`) plus if it was decided to include traits included by
traits then a similar check or recursive call to get traits used by
each trait in the array).

Reply via email to