如何检查名称空间中是不是存在类?
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”(您是不是缺少程序集引用?)
命名空间“Microsoft”中不存在类型或命名空间名称“AspNetCore”(您是不是缺少程序集引用?)
命名空间“System.Configuration”中不存在类型或命名空间名称“ConfigurationManager”