注意,一个特质可能会使用其他特质,所以类可能不直接使用该特质。而且这个类可能是从使用该特质的父类继承而来的。
这是一个可以在几行代码内解决的问题还是我需要循环做些什么?
这是一个可以在几行代码内解决的问题还是我需要循环做些什么?
如果在使用 Laravel 框架时遇到问题,可以使用 class_uses_recursive()
函数。
https://laravel.com/docs/8.x/helpers#method-class-uses-recursive
因此,您可以像这样做:
in_array(SomeTrait::class, class_uses_recursive(SomeClass::class))
在特征列表中检查您的特征:
$usingTrait = in_array(
MyTrait::class,
array_keys((new \ReflectionClass(MyClass::class))->getTraits())
);
如果MyClass
使用MyTrait
,则返回true或false
class_uses
иАМи¶БдљњзФ®еПНе∞ДеСҐпЉЯ - abdulmanov.ilmirclass_uses
一样 - 它们都不能返回父类中定义的特性。 - jave.web如果你想要检查类使用的特质,你可以使用class_uses
函数,它将仅返回该类所使用的所有特质的数组。
in_array(SoftDeletes::class, class_uses(Model::class), true) //return boolean
如果你想检查类或其父类是否使用了 trait,请使用class_uses_recursive
函数。
in_array(SoftDeletes::class, class_uses_recursive(Model::class), true) //return boolean
另一种方法是使用定义您的特性所期望的接口。然后,您可以使用"instanceof SomeInterface"而不是进行反射或鸭子类型。
通常,检查你打算使用的API部分是否存在是一个很好的替代方式。
method_exists(mixed $object, string $method_name): bool
此外,如@MeatPopsicle所提到的,Trait经常与(标记)接口结合使用。
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);
}
我在这个主题上遇到了一些问题,写了一个解决方案,想与大家分享。通过使用 new ReflectionClass($objectOrClass)
,您可以使用实例方法 getTraits()
。问题在于它只返回$objectOrClass
的特征数组,而不是从特征或扩展类继承的特征。
以下是解决方案:
/** @return ReflectionClass[] */
function get_reflection_class_traits( ReflectionClass $reflection, array $traits = [] ): array {
if ( $reflection->getParentClass() ) {
$traits = get_reflection_class_traits( $reflection->getParentClass(), $traits );
}
if ( ! empty( $reflection->getTraits() ) ) {
foreach ( $reflection->getTraits() as $trait_key => $trait ) {
$traits[$trait_key] = $trait;
$traits = get_reflection_class_traits( $trait, $traits );
}
}
return $traits;
}
// string|object $objectOrClass Either a string containing the name of the class to reflect, or an object.
$objectOrClass = //...
$reflection = new ReflectionClass( $objectOrClass );
$all_traits = $this->get_reflection_class_traits( reflection );
这是我在我的工具类中拥有的内容
static function
isTrait( $object, $traitName, $autoloader = true )
{
$ret = class_uses( $object, $autoloader ) ;
if( is_array( $ret ) )
{
$ret = array_search( $traitName, $ret ) !== false ;
}
return $ret ;
}
array_keys((new \ReflectionClass($object))->getTraits()