2024 PHP Conference Japan

class_exists

(PHP 4, PHP 5, PHP 7, PHP 8)

class_exists檢查類別是否已定義

說明

class_exists(字串 $class, 布林值 $autoload = true): 布林值

此函式檢查指定的類別是否已定義。

參數

class

類別名稱。名稱比對不區分大小寫。

autoload

是否在尚未載入時進行 自動載入

回傳值

如果 class 是一個已定義的類別,則回傳 true,否則回傳 false

範例

範例 #1 class_exists() 範例

<?php
// 在嘗試使用類別之前,檢查該類別是否存在
if (class_exists('MyClass')) {
$myclass = new MyClass();
}

?>

範例 #2 autoload 參數範例

<?php
spl_autoload_register
(function ($class_name) {
include
$class_name . '.php';

// 檢查 include 是否已宣告該類別
if (!class_exists($class_name, false)) {
throw new
LogicException("無法載入類別: $class_name");
}
});

if (
class_exists(MyClass::class)) {
$myclass = new MyClass();
}

?>

參見

新增註釋

使用者貢獻的註釋 9 則註釋

49
giunta dot gaetano at gmail dot com
11 年前
如果您使用別名來導入命名空間的類別,請注意 class_exists 無法使用簡短的別名類別名稱 - 顯然地,每當類別名稱以字串形式使用時,只能使用完整的命名空間版本

use a\namespaced\classname as coolclass;

class_exists( 'coolclass' ) => false
11
info at ensostudio dot ru
4 年前
注意:class_exists() 只檢查類別!
<?php
介面 DemoInterface {};
var_dump(class_exists('DemoInterface')); // false
trait DemoTrait {};
var_dump(class_exists('DemoTrait')); // false
類別 DemoClass {};
var_dump(class_exists('DemoClass')); // true
?>

通用函式
<?php
/**
* 檢查類別/trait/介面是否已定義。
*
* @param string $name 類別/trait/介面的名稱(不區分大小寫)
* @param bool $autoload 是否呼叫 spl_autoload()
* @return bool
*/
函式 structure_exists(string $name, bool $autoload = true): bool
{
return
class_exists($name, $autoload)
||
interface_exists($name, $autoload)
||
trait_exists($name, $autoload);
}
?>
15
rn at alpha9marketing dot com
10 年前
注意:class_exists 不區分大小寫,類別實例化也是如此。

php > var_dump(class_exists("DomNode"));
bool(true)
php > var_dump(class_exists("DOMNode"));
bool(true)
php > var_dump(class_exists("DOMNodE"));
bool(true)
php > $x = new DOMNOdE();
php > var_dump(get_class($x));
string(7) "DOMNode"

(在 Linux 上使用 PHP 5.5.10 測試)

這可能會在將類別名稱與檔案名稱關聯時造成一些困擾,尤其是在區分大小寫的檔案系統上。
13
Klaus
14 年前
如果您在自動載入函式中遞迴載入多個類別(或混合手動載入和自動載入),請注意 class_exists()(以及 get_declared_classes())不知道在*目前*自動載入呼叫期間先前載入的類別。

顯然,已宣告類別的內部清單僅在自動載入函式完成後才會更新。
13
spam at wikicms dot org
10 年前
嗨,各位!
在 spl_autoload_register 之後檢查類別是否存在時,請小心並不要忘記第二個布林值參數 $autoload(預設為 TRUE)。以下提供一個簡短的範例:
檔案 second.php
<?php
類別 Second {}
?>
檔案 index.php
<?php
類別 First
{
函式
first($class, $bool) {
spl_autoload_register( 函式($class) {
require
strtolower($class) . '.php';
});
echo
class_exists($class, $bool)?'存在!':'不存在!';
}
}

new
First($class = 'Second', $bool = true); //存在!
new First($class = 'Second', $bool = false); //不存在!
?>
因為 __autoload 的執行比布林值返回早得多,依我拙見..
2
sb at firstvector dot org
5 個月前
注意 `\class_exists()` 會針對列舉類型回傳 `true`。

<?php
enum Test: int
{
case
One = 1;
case
Two = 2;
}

\var_dump(\class_exists(Test::class)); // bool(true)
?>

考慮到這一點,檢查類別是否存在的正確方法是

<?php
函式 is_class_exist(string $class): bool
{
return
\class_exists($class) && !\enum_exists($class);
}
?>
10
richard at richard-sumilang dot com
16 年前
[ >= PHP 5.3]

如果您正在檢查特定命名空間中是否存在某個類別,則必須傳入該類別的完整路徑

echo (class_exists("com::richardsumilang::common::MyClass")) ? "Yes" : "No";
2
anonymous at somewhere dot tld
21 年前
如果您有一個想要建立的類別目錄(在我的例子中是模組)...您可以這樣做

<?php
if (is_dir($this->MODULE_PATH) && $dh = opendir($this->MODULE_PATH)) {
while ((
$file = readdir($dh)) !== false) {
if (
preg_match("/(Mod[a-zA-Z0-9]+).php/", $file, $matches)>0) {
// 引用並建立類別
require_once($this->MODULE_PATH."/".$file);
$modules[] = new $matches[1]();
}
}
} else {
exit;
}
?>

//---
這裡的規則是所有模組的格式都為
ModModulename.php 而且類別名稱與檔案名稱相同。
執行這段程式碼後,`$modules` 陣列將包含所有已初始化的類別。
1
toocoolone at gmail dot com
12 年前
我在 Windows 7 上執行 PHP 5.3.4,使用 `class_exists()` 自動載入類別時遇到一些困難。在我的情況下,當我檢查類別不存在時,`class_exists()` 會自動拋出系統例外。我也拋出了自己的例外,導致未捕獲的例外。

<?php
/**
* 在此設定我的 include 路徑
*/
$include_path = array( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
/**
* 假設我有自己的自訂例外處理器 (MyException),讓我們
* 嘗試看看檔案是否存在。
*/
try {
if( !
file_exists( 'myfile.php' ) ) {
throw new
MyException('糟糕!');
}
include(
'myfile.php' );
}
catch(
MyException $e ) {
echo
$e->getMessage();
}
/**
* 上面的程式碼會包含 myfile.php 或擲出新的 MyException
* 如預期。沒問題吧?class_exists() 也應該一樣,
* 對吧?那麼...
*/
$classname = 'NonExistentClass';
try {
if( !
class_exists( $classname ) ) {
throw new
MyException('真是糟糕!');
}
$var = new $classname();
}
catch(
MyException $e ) {
echo
$e->getMessage();
}
/**
* 應該要擲出一個新的 MyException 實例。但相反地,我得到一個
* 未捕捉的 LogicException 等等,這是預設 Exception
* 類別和 MyException 的錯誤。我只捕捉 MyException,所以我們有一個
* 未捕捉的例外,導致可怕的 LogicException 錯誤。
*/
?>

透過註冊一個額外的、不做任何事的自動載入處理函式,我就能夠停止擲出額外的例外,只擲出我自己的例外。

<?php
/**
* 在此設定我的 include 路徑
*/
$include_path = array( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
spl_autoload_register( 'myAutoLoad' ); // 加上這兩行就沒問題了...
function myAutoLoad() {}
/**
* 透過註冊一個額外的、不做任何事的自訂自動載入函式
* class_exists() 只會回傳布林值,而不會擲出未捕捉的例外
*/
?>

在一些搜尋結果中發現了這個。我不記得頁面的網址,但如果它在這裡的話,可能會幫我省下一些時間!
To Top