class_uses
(PHP 5 >= 5.4.0)
class_uses — Return the traits used by the given class
Description
This function returns an array with the names of the traits that the
given class
uses. This does however not include
any traits used by a parent class.
Parameters
-
class
-
An object (class instance) or a string (class name).
-
autoload
-
Whether to allow this function to load the class automatically through the __autoload() magic method.
Return Values
An array on success, or FALSE
on error.
Examples
Example #1 class_uses() example
<?php
trait foo { }
class bar {
use foo;
}
print_r(class_uses(new bar));
print_r(class_uses('bar'));
function __autoload($class_name) {
require_once $class_name . '.php';
}
// use __autoload to load the 'not_loaded' class
print_r(class_uses('not_loaded', true));
?>
The above example will output something similar to:
Array ( [foo] => foo ) Array ( [foo] => foo ) Array ( [trait_of_not_loaded] => trait_of_not_loaded )
See Also
- class_parents() - Return the parent classes of the given class
- get_declared_traits() - Returns an array of all declared traits
Коментарии
To get ALL traits including those used by parent classes and other traits, use this function:
<?php
function class_uses_deep($class, $autoload = true) {
$traits = [];
do {
$traits = array_merge(class_uses($class, $autoload), $traits);
} while($class = get_parent_class($class));
foreach ($traits as $trait => $same) {
$traits = array_merge(class_uses($trait, $autoload), $traits);
}
return array_unique($traits);
}
?>
A slighly modified version from Stealz that also checks all the "parent" traits used by the traits:
<?php
public static function class_uses_deep($class, $autoload = true)
{
$traits = [];
// Get traits of all parent classes
do {
$traits = array_merge(class_uses($class, $autoload), $traits);
} while ($class = get_parent_class($class));
// Get traits of all parent traits
$traitsToSearch = $traits;
while (!empty($traitsToSearch)) {
$newTraits = class_uses(array_pop($traitsToSearch), $autoload);
$traits = array_merge($newTraits, $traits);
$traitsToSearch = array_merge($newTraits, $traitsToSearch);
};
foreach ($traits as $trait => $same) {
$traits = array_merge(class_uses($trait, $autoload), $traits);
}
return array_unique($traits);
}
?>
If the class does not exist, you will get a warning, even if $autoload == false; I.e., if the class is not found, setting $autoload to false is not sufficient to silence the warning.
This is different from class_exists ($class_name, $autoload = true), which doesn't generate a warning in either case.
I have improved on ulf's improvement of stealz' code. I'm pretty sure the last "foreach" adds nothing, so I've removed it, as well as adding a check for string class names (as opposed to objects) to prevent the warning if the class is not found:
<?php
function class_uses_deep($class, $autoload = true) {
$traits = [];
// Get all the traits of $class and its parent classes
do {
$class_name = is_object($class)? get_class($class): $class;
if (class_exists($class_name, $autoload)) {
$traits = array_merge(class_uses($class, $autoload), $traits);
}
} while ($class = get_parent_class($class));
// Get traits of all parent traits
$traits_to_search = $traits;
while (!empty($traits_to_search)) {
$new_traits = class_uses(array_pop($traits_to_search), $autoload);
$traits = array_merge($new_traits, $traits);
$traits_to_search = array_merge($new_traits, $traits_to_search);
};
return array_unique($traits);
}
Another alternative to get all parent traits is:
<?php
function getUsedTraits($classInstance) {
$parentClasses = class_parents($classInstance);
$traits = class_uses($classInstance);
foreach ($parentClasses as $parentClass) {
$traits = array_merge($traits, class_uses($parentClass));
}
return $traits;
}
?>
The popular stealz solution doesn't handle traits that use other traits. A little bit of recursion can clean the entire thing up a bit and make it more robust.
<?php
public function class_uses_deep( string $class, bool $autoload = true ) : array {
$traits = class_uses($class, $autoload);
if($parent = get_parent_class($class)) {
$traits = array_merge($traits, class_uses_deep($parent, $autoload));
}
foreach( $traits as $trait ) {
$traits = array_merge($traits, class_uses_deep($trait, $autoload));
}
return $traits;
}
?>