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).
