2024 PHP Conference Japan

class_uses

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

class_uses 傳回指定類別使用的 traits

說明

class_uses(物件|字串 $object_or_class, 布林值 $autoload = true): 陣列|false

此函式會傳回一個陣列,其中包含指定 object_or_class 使用的 traits 名稱。 但這不包含父類別使用的任何 traits。

參數

物件或類別

一個物件(類別實例)或一個字串(類別名稱)。

自動載入

如果尚未載入,是否要自動載入

回傳值

成功時返回一個陣列,當指定的類別不存在時返回 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 則註釋

35
stealz at op dot pl
12 年前
要取得所有 traits,包含父類別和其他 traits 使用的 traits,請使用以下函式

<?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);
}
?>
8
Jos Macedo
4 年前
另一種取得所有父 traits 的方法是

<?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;
}
?>
17
ulf
11 年前
這是 Stealz 版本的略微修改版,它還會檢查 traits 使用的所有「父」traits

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

// 取得所有父類別的 traits
do {
$traits = array_merge(class_uses($class, $autoload), $traits);
} while (
$class = get_parent_class($class));

// 取得所有父 traits 的 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);
}
?>
4
Daniel Klein
6 年前
如果類別不存在,即使 $autoload == false,您也會收到警告;也就是說,如果找不到類別,將 $autoload 設定為 false 並不足以抑制警告。

這與 class_exists ($class_name, $autoload = true) 不同,後者在任何一種情況下都不會產生警告。
4
Daniel Klein
6 年前
我改進了 ulf 對 stealz 程式碼的改進。我很確定最後的「foreach」沒有增加任何東西,所以我刪除了它,並添加了對字串類別名稱(而不是物件)的檢查,以防止在找不到類別時發出警告。

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

// 取得 $class 及其所有父類別的所有 Traits
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));

// 取得所有父 Traits 的 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);
}
0
donatj at gmail dot com
3 年前
廣為流傳的 stealz 解法並未處理使用其他 Traits 的 Traits。稍微運用遞迴即可整理程式碼,並使其更加穩固。

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