class_exists

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

class_exists检查类是否已定义

说明

class_exists(string $class, bool $autoload = true): bool

此函数检查给定类是否已定义。

参数

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();
}

?>

参见

添加笔记

用户贡献笔记 10 笔记

49
giunta dot gaetano at gmail dot com
10 年前
如果您使用别名来导入命名空间类,请注意,class_exists 将无法使用简短的别名类名 - 显然,只要类名用作字符串,就只能使用完整的命名空间版本

use a\namespaced\classname as coolclass;

class_exists( 'coolclass' ) => false
11
info at ensostudio dot ru
3 年前
注意:class_exists() 只检查类!
<?php
interface DemoInterface {};
var_dump(class_exists('DemoInterface')); // false
trait DemoTrait {};
var_dump(class_exists('DemoTrait')); // false
class DemoClass {};
var_dump(class_exists('DemoClass')); // true
?>

常用函数
<?php
/**
* 检查类/特性/接口是否已定义。
*
* @param string $name 类/特性/接口的不区分大小写的名称
* @param bool $autoload 是否调用 spl_autoload()
* @return bool
*/
function 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
class Second {}
?>
文件 index.php
<?php
class First
{
function
first($class, $bool) {
spl_autoload_register( function($class) {
require
strtolower($class) . '.php';
});
echo
class_exists($class, $bool)?'Exist!!!!':'Not exist!';
}
}

new
First($class = 'Second', $bool = true); //Exist!!!!
new First($class = 'Second', $bool = false); //Not exist!
?>
因为 __autoload 执行得比布尔值返回早得多,恕我直言。
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 数组将包含所有初始化的类
2
sb at firstvector dot org
1 个月前
请注意,`\class_exists()` 对枚举返回 `true`。

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

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

考虑到这一点,正确检查类是否存在的方法是

<?php
function is_class_exist(string $class): bool
{
return
\class_exists($class) && !\enum_exists($class);
}
?>
1
toocoolone at gmail dot com
12 年前
我在 Windows 7 上运行 PHP 5.3.4,在使用 class_exists() 自动加载类时遇到了一些困难。在我的情况下,当我检查类是否存在时,如果它不存在,class_exists 会自动抛出一个系统异常。我也在抛出我自己的异常,导致一个未捕获的异常。

<?php
/**
* 在这里设置我的包含路径
*/
$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('Doh!');
}
include(
'myfile.php' );
}
catch(
MyException $e ) {
echo
$e->getMessage();
}
/**
* 上面的代码要么包含 myfile.php,要么按预期抛出新的 MyException。
* 没有问题,对吧?class_exists() 应该也是这样,
* 对吧?那么...
*/
$classname = 'NonExistentClass';
try {
if( !
class_exists( $classname ) ) {
throw new
MyException('Double Doh!');
}
$var = new $classname();
}
catch(
MyException $e ) {
echo
$e->getMessage();
}
/**
* 应该抛出一个新的 MyException 实例。但是,我却得到了
* 未捕获的 LogicException 等等,用于默认的 Exception
* 类和 MyException。我只捕获 MyException,因此我们有一个
* 未捕获的异常,导致可怕的 LogicException 错误。
*/
?>

通过注册一个不做任何事情的额外自动加载处理程序函数,我能够停止抛出额外的异常,而只抛出我自己的异常。

<?php
/**
* 在这里设置我的包含路径
*/
$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() 仅返回布尔值,不会抛出未捕获的异常
*/
?>

我在一些搜索结果中找到了这个。我不记得页面 URL,但如果它在这里,可能就节省了我一些时间!
-14
azrael dot com at gmail dot com
15 年前
如果调用了 spl_autoload_register(),那么该函数会在类不存在时尝试自动加载类。

改用
<?php
in_array
($class_name, get_declared_classes());
?>
To Top