略微加速

PHP官方手册 - 互联网笔记

PHP - Manual: class_uses

2024-11-13

class_uses

(PHP 5 >= 5.4.0, PHP 7, PHP 8)

class_uses Return the traits used by the given class

说明

class_uses(object|string $object_or_class, bool $autoload = true): array|false

This function returns an array with the names of the traits that the given object_or_class uses. This does however not include any traits used by a parent class.

参数

object_or_class

An object (class instance) or a string (class name).

autoload

Whether to call __autoload by default.

返回值

An array on success, or false when the given class doesn't exist.

范例

示例 #1 class_uses() example

<?php

trait foo { }
class 
bar {
  use 
foo;
}

print_r(class_uses(new bar));

print_r(class_uses('bar'));

spl_autoload_register();

// use autoloading to load the 'not_loaded' class
print_r(class_uses('not_loaded'true));

?>

以上例程的输出类似于:

Array
(
    [foo] => foo
)
Array
(
    [foo] => foo
)
Array
(
    [trait_of_not_loaded] => trait_of_not_loaded
)

参见

add a noteadd a note

User Contributed Notes 7 notes

up
34
stealz at op dot pl
9 years ago
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);
}
?>
up
9
Jos Macedo
1 year ago
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;
}
?>
up
2
donatj at gmail dot com
1 year ago
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;
}

?>
up
14
ulf
8 years ago
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);
    }
?>
up
3
Daniel Klein
4 years ago
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.
up
2
Daniel Klein
4 years ago
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);
}
up
-43
adam at adamhahn dot com
9 years ago
FYI: It is not explicitly stated, but if you run this function against a class that does not use any traits it will return an empty array.

<?php

class iDontUseTraits {
}

class_uses('iDontUseTraits'); // Returns empty array

?>

官方地址:https://www.php.net/manual/en/function.class-uses.php

北京半月雨文化科技有限公司.版权所有 京ICP备12026184号-3