如果您使用别名来导入命名空间类,请注意 class_exists 将无法使用简短的、带别名的类名 - 显然,每当类名用作字符串时,只能使用完整命名空间版本。
use a\namespaced\classname as coolclass;
class_exists( 'coolclass' ) => false
(PHP 4, PHP 5, PHP 7, PHP 8)
class_exists — 检查类是否已定义
示例 #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();
}
?>
如果您使用别名来导入命名空间类,请注意 class_exists 将无法使用简短的、带别名的类名 - 显然,每当类名用作字符串时,只能使用完整命名空间版本。
use a\namespaced\classname as coolclass;
class_exists( 'coolclass' ) => false
注意: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);
}
?>
注意: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 测试)
这可能会导致在将类名与文件名相关联时出现一些问题,尤其是在区分大小写的文件系统上。
如果您在自动加载函数中递归加载多个类(或混合手动加载和自动加载),请注意 class_exists()(以及 get_declared_classes())不知道在*当前*自动加载调用期间先前加载的类。
显然,已声明类的内部列表仅在自动加载函数完成后更新。
大家好!
请注意,在 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 的执行时间远早于布尔值的返回,恕我直言。
注意 `\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);
}
?>
[ >= PHP 5.3]
如果您正在检查是否存在特定命名空间中的类,则必须传入类的完整路径
回显 (class_exists("com::richardsumilang::common::MyClass")) ? "是" : "否";
如果您要创建类目录。(在我的示例中是模块)...您可以这样做
<?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` 数组包含所有已初始化的类
我在 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,但如果它在这里,它可能会为我节省一些时间!