如何检查命名空间中是否存在类?

时间:2014-03-14 14:09:42

标签: php oop namespaces

我有这个:

    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不存在的类的对象)。有没有办法检查给定名称空间下是否存在类?

2 个答案:

答案 0 :(得分:89)

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

namespace Foo;
class Bar
{
}

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

-i.e。您必须指定课程的完整路径。您在命名空间中而不是在全局上下文中定义它。

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

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

答案 1 :(得分:25)

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

PHP 5.5为此目的引入了class常量:

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