如何检查名称空间内是否存在类?
我有这个:
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;
那么…这种行为是非常不合理的(创build根据PHP的类的对象不存在)。 有什么办法来检查一个类是否存在于给定的命名空间下?
为了检查类,你必须指定它与命名空间,完整path:
namespace Foo; class Bar { }
和
var_dump(class_exists('Bar'), class_exists('\\Foo\\Bar')); //false, true
– 你必须指定类的完整path。 你在你的命名空间中定义它,而不是在全局上下文中。
但是,如果您像在示例中那样在命名空间中导入了类,则可以通过导入的名称和名称空间来引用它,但不允许在dynamic结构中执行此操作,特别是内联string形成class级名称。 例如,以下所有将失败:
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
等等。 问题在于为import别名工作的机制。 所以,当使用这样的结构时,你必须指定完整的path:
var_dump(class_exists('\Foo\Bar')); //true var_dump(method_exists('\Foo\Bar', 'baz')); //true $ref = 'Foo\Bar'; $obj = new $ref(); //ok
这个问题(在class_exists()
手册页的用户注释中提到)是,只要给出一个类名作为string,就不会考虑别名。 这也会影响其他带有类名的函数,比如is_a()
。 因此,如果您在string中input类名称,则必须包含完整的名称空间(例如'\XXX\Driver\Driver'
, 'XXX\\Driver\\Driver'
)。
为了这个目的,PHP 5.5引入了class
常量:
use XXX\Driver\Driver; ... if (class_exists(Driver::class)) { ... }