请注意,特征可能会使用其他特征,因此该类可能不会直接使用该特征。并且该类可以从使用该特征的父类继承。
这是一个可以在几行内解决的问题,还是我必须做一些循环?
答案 0 :(得分:7)
class_uses()函数将返回一个数组,其中包含该类使用的所有特征的名称,并通过传递类名或实例来工作....但是,您需要"递归"通过继承树获取所有使用的特征,并通过每个特征
修改强>
请注意,string myFormat = dt.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture);
提供了一个示例函数,显示如何在链接的PHP文档页面的评论部分中执行此递归
答案 1 :(得分:5)
在特征列表中检查您的特征:
$usingTrait = in_array(
MyTrait::class,
array_keys((new \ReflectionClass(MyClass::class))->getTraits())
);
如果 MyClass 使用 MyTrait
,则返回true或false答案 2 :(得分:4)
如果任何人在使用Laravel框架时遇到此问题,则该函数具有名为NewsItem
的帮助程序功能。
https://laravel.com/docs/8.x/helpers#method-class-uses-recursive
答案 3 :(得分:2)
解决此问题的另一种方法是使用定义期望性状的接口。然后,您将使用“ instanceof SomeInterface”而不是进行反射或鸭子输入。
答案 4 :(得分:1)
这是我的“工具”课程中的内容
static function
isTrait( $object, $traitName, $autoloader = true )
{
$ret = class_uses( $object, $autoloader ) ;
if( is_array( $ret ) )
{
$ret = array_search( $traitName, $ret ) !== false ;
}
return $ret ;
}
答案 5 :(得分:0)
以下功能来自http://php.net/manual/en/function.class-uses.php,ulf的评论。效果很好。
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);
}
答案 6 :(得分:0)
通常,检查您打算使用的API部分是否足够替代。
method_exists ( mixed $object , string $method_name ) : bool
此外,正如@MeatPopsicle所提到的,特征通常与(marker-)接口结合使用。
答案 7 :(得分:0)
如果你只想检查类,你可以使用 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