【问题标题】: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 oop namespaces


【解决方案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)) {
    ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 2012-01-19
    • 2018-04-04
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2013-06-02
    相关资源
    最近更新 更多