如何检查名称空间中是不是存在类?

Posted

技术标签:

【中文标题】如何检查名称空间中是不是存在类?【英文标题】:How to check if class exists within a namespace?如何检查名称空间中是否存在类? 【发布时间】:2014-04-19 21:13:15 【问题描述】:

我有这个:

    use XXX\Driver\Driver;

...

var_dump(class_exists('Driver')); // false
        $driver = new Driver(); // prints 123123123 since I put an echo in the constructor of this class
        exit;

嗯...这种行为是非常不合理的(创建根据 php 不存在的类的对象)。有没有办法检查给定命名空间下是否存在一个类?

【问题讨论】:

php.net/class_exists 看看 cmets 如何给定命名空间 另见“Is there a namespace aware alternative to PHP's class_exists()?” 【参考方案1】:

为了检查类,您必须使用命名空间、完整路径来指定它:

namespace Foo;
class Bar


var_dump(class_exists('Bar'), class_exists('\Foo\Bar')); //false, true

-即您必须指定类的完整路径。您在命名空间中定义它,而不是在全局上下文中。

但是,如果您确实像在示例中那样在命名空间中导入类,则可以通过导入的名称而不使用命名空间来引用它,但这不允许您在动态构造中执行此操作,特别是在 -形成类名的行字符串。例如,以下所有操作都会失败:

namespace Foo;
class Bar 
    public static function baz()  


use Foo\Bar;

var_dump(class_exists('Bar')); //false
var_dump(method_exists('Bar', 'baz')); //false

$ref = "Bar";
$obj = new $ref(); //fatal

等等。问题在于为导入的别名工作的机制。因此,在使用此类结构时,您必须指定完整路径:

var_dump(class_exists('\Foo\Bar')); //true
var_dump(method_exists('\Foo\Bar', 'baz')); //true

$ref = 'Foo\Bar';
$obj = new $ref(); //ok

【讨论】:

请注意,Driver 已在问题中导入,因此此答案中的最后一个示例并未描述相关情况。 use \Foo\Bar; $obj = new Bar; 完全合法。真正的问题是class_exists() 没有考虑别名。 @outis,谢谢。在收到您的评论之前,我一直处于无限循环中。 @san.chez 虽然说的是真的,但真正的问题不在于class_exists,而在于PHP 和别名实体的替换机制。添加了引用通用案例的说明。 class_exists('\\Foo\\Bar') 不需要双斜杠,因为它对字符串使用单引号语法。 php.net/manual/en/language.namespaces.dynamic.php @AlmaDo,老实说,我不确定你从哪里得到你的信息。但归根结底,您可以做任何适合您的解决方案。 PHP 5.5 于 2013 年 6 月 20 日发布(在php.net/releases/index.php#5.5.0 查找 ip),这个问题是在 2014 年 3 月 14 日提出的。这个问题的答案怎么可能先于问题本身,更不用说 PHP 5.5 的发布日期了?使用::class 永远不会产生多个结果。这怎么可能?关键是......你的答案对我的用例不起作用。我必须使用我现在在生产中使用的@outis 解决方案。【参考方案2】:

问题(如class_exists() 手册页用户注释中所述)是,只要将类名作为字符串给出,就不会考虑别名。这也会影响其他采用类名的函数,例如is_a()。因此,如果您在字符串中给出类名,则必须包含完整的命名空间(例如'\XXX\Driver\Driver''XXX\\Driver\\Driver')。

PHP 5.5 引入了class 常量就是为了这个目的:

use XXX\Driver\Driver;
...
if (class_exists(Driver::class)) 
    ...

【讨论】:

以上是关于如何检查名称空间中是不是存在类?的主要内容,如果未能解决你的问题,请参考以下文章

错误 CS0234 名称空间“MvvmCross”中不存在类型或名称空间名称“Platforms”(您是不是缺少程序集引用?)

创建类图时出现“名称空间中已存在”消息

从类引用中获取类命名空间和名称,而不更改我的类

C# - 如何检查 C# 中是不是存在命名空间、类或方法?

命名空间“Microsoft”中不存在类型或命名空间名称“AspNetCore”(您是不是缺少程序集引用?)

命名空间“System.Configuration”中不存在类型或命名空间名称“ConfigurationManager”