2024年PHP开发者大会日本站

class_uses

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

class_uses返回给定类使用的 trait

描述

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

此函数返回一个数组,其中包含给定 object_or_class 使用的 trait 的名称。但是,这并不包括父类使用的任何 trait。

参数

object_or_class

一个对象(类实例)或一个字符串(类名)。

autoload

是否自动加载(如果尚未加载)。

返回值

成功时返回一个数组,如果给定的类不存在则返回 false

示例

示例 #1 class_uses() 示例

<?php

trait foo { }
class
bar {
use
foo;
}

print_r(class_uses(new bar));

print_r(class_uses('bar'));

spl_autoload_register();

// 使用自动加载来加载 'not_loaded' 类
print_r(class_uses('not_loaded', true));

?>

以上示例将输出类似以下内容

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

参见

添加笔记

用户贡献笔记 6 条笔记

stealz at op dot pl
12年前
要获取所有 trait(包括父类和其他 trait 使用的 trait),请使用此函数

<?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);
}
?>
Jos Macedo
4年前
另一种获取所有父级 trait 的方法是

<?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;
}
?>
ulf
11年前
Stealz 的一个稍微修改后的版本,它还检查 trait 使用的所有“父”trait

<?php
public static function class_uses_deep($class, $autoload = true)
{
$traits = [];

// 获取所有父类的 trait
do {
$traits = array_merge(class_uses($class, $autoload), $traits);
} while (
$class = get_parent_class($class));

// 获取所有父级 trait 的 trait
$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);
}
?>
Daniel Klein
6年前
如果类不存在,即使 $autoload == false,也会出现警告;也就是说,如果找不到类,将 $autoload 设置为 false 也不足以消除警告。

这与 class_exists ($class_name, $autoload = true) 不同,后者在任何情况下都不会生成警告。
Daniel Klein
6年前
我已经改进了 ulf 对 stealz 代码的改进。我很确定最后一个“foreach”没有添加任何内容,所以我将其删除了,并添加了对字符串类名(而不是对象)的检查,以防止在找不到类时出现警告

<?php
function class_uses_deep($class, $autoload = true) {
$traits = [];

// 获取$class及其父类的所有trait
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));

// 获取所有父trait的trait
$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);
}
donatj at gmail dot com
3年前
流行的stealz解决方案无法处理使用其他trait的trait。一些递归可以清理整个过程,并使其更加健壮。

<?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;
}

?>
To Top