PHP Conference Japan 2024

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 条注释

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

use a\namespaced\classname as coolclass;

class_exists( 'coolclass' ) => false
info at ensostudio dot ru
4 年前
注意: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);
}
?>
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 测试)

这可能会导致在将类名与文件名相关联时出现一些问题,尤其是在区分大小写的文件系统上。
Klaus
14 年前
如果您在自动加载函数中递归加载多个类(或混合手动加载和自动加载),请注意 class_exists()(以及 get_declared_classes())不知道在*当前*自动加载调用期间先前加载的类。

显然,已声明类的内部列表仅在自动加载函数完成后更新。
spam at wikicms dot org
10 年前
大家好!
请注意,在 spl_autoload_register 后检查类是否存在时,不要忘记第二个布尔参数 $autoload(默认为 TRUE)。建议一个简短的示例
文件 second.php
<?php
class Second {}
?>
文件 index.php
<?php
First
{
函数
first($class, $bool) {
spl_autoload_register( 函数($class) {
引用
strtolower($class) . '.php';
});
回显
class_exists($class, $bool)?'存在!!!!':'不存在!';
}
}

First($class = 'Second', $bool = true); //存在!!!!
First($class = 'Second', $bool = false); //不存在!
?>
因为 __autoload 的执行时间远早于布尔值的返回,恕我直言。
sb at firstvector dot org
5 个月前
注意 `\class_exists()` 会对枚举返回 `true`。

<?php
枚举 Test: int
{
案例
One = 1;
案例
Two = 2;
}

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

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

<?php
函数 is_class_exist(字符串 $class): 布尔值
{
返回
\class_exists($class) && !\enum_exists($class);
}
?>
richard at richard-sumilang dot com
16 年前
[ >= PHP 5.3]

如果您正在检查是否存在特定命名空间中的类,则必须传入类的完整路径

回显 (class_exists("com::richardsumilang::common::MyClass")) ? "是" : "否";
anonymous at somewhere dot tld
21 年前
如果您要创建类目录。(在我的示例中是模块)...您可以这样做

<?php
如果 (is_dir($this->MODULE_PATH) && $dh = opendir($this->MODULE_PATH)) {
当 ((
$file = readdir($dh)) !== false) {
如果 (
preg_match("/(Mod[a-zA-Z0-9]+).php/", $file, $matches)>0) {
// 包含并创建类
引用一次($this->MODULE_PATH."/".$file);
$modules[] = 新 $matches[1]();
}
}
} 否则 {
退出;
}
?>

//---
此处的规则是所有模块都采用以下形式
ModModulename.php,并且类与文件同名。
此代码执行后,`$modules` 数组包含所有已初始化的类
toocoolone at gmail dot com
12 年前
我在 Windows 7 上运行 PHP 5.3.4,并且在使用 class_exists() 自动加载类时遇到了一些困难。在我的情况下,当我检查类是否存在并且它不存在时,class_exists 会自动抛出一个系统异常。我也在抛出我自己的异常,导致未捕获的异常。

<?php
/**
* 在此处设置我的包含路径
*/
$include_path = 数组( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
/**
* 假设我有自己的自定义异常处理程序 (MyException),让我们
* 尝试查看文件是否存在。
*/
尝试 {
如果( !
file_exists( 'myfile.php' ) ) {
抛出新
MyException('Doh!');
}
包含(
'myfile.php' );
}
捕获(
MyException $e ) {
回显
$e->getMessage();
}
/**
* 上述代码包含 myfile.php 或抛出新的 MyException
* 如预期的那样。没问题吧?class_exists() 也应该如此,
* 对吧?那么...
*/
$classname = 'NonExistentClass';
尝试 {
如果( !
class_exists( $classname ) ) {
抛出新
MyException('Double Doh!');
}
$var = 新 $classname();
}
捕获(
MyException $e ) {
回显
$e->getMessage();
}
/**
* 应该抛出一个新的 MyException 实例。但相反,我得到了一个
* 未捕获的 LogicException 等等,用于默认的 Exception
* 类和 MyException。我只捕获 MyException,所以我们有一个
* 未捕获的结果导致了可怕的 LogicException 错误。
*/
?>

通过注册一个什么也不做的额外自动加载处理程序函数,我能够停止抛出额外的异常,并且只抛出我自己的异常。

<?php
/**
* 在此处设置我的包含路径
*/
$include_path = 数组( '/include/this/dir', '/include/this/one/too' );
set_include_path( $include_path );
spl_autoload_register();
spl_autoload_register( 'myAutoLoad' ); // 添加这两个,不用担心...
函数 myAutoLoad() {}
/**
* 通过注册什么也不做的额外自定义自动加载函数
* class_exists() 仅返回布尔值,并且不会抛出未捕获的异常
*/
?>

在一些搜索结果中发现了这一点。我不记得页面 URL,但如果它在这里,它可能会为我节省一些时间!
To Top