一个基本的用例是在没有导入use MyNamespaceMyEventListener
的情况下调用MyEventListener::class
。结果将是一段相对难以调试的损坏代码。
如果不存在类,PHP 7 是否提供崩溃指令而不是返回类名?例如:
打电话给use FooBar;
后,Bar::class
会返回'FooBar'
。
但是如果没有导入语句,PHP 会返回'Bar'
,即使该类不存在,甚至在全局命名空间中也不存在。
我可以以某种方式让它崩溃吗?
您需要记住的是,use FooBar;
并没有"导入"任何东西。它告诉编译器:当我说"Bar"时,我的意思是Bar
来自命名空间Foo
。
Bar::class
被盲目地替换为字符串"Foo\Bar"。它没有检查任何东西。
在您尝试实例化类或与类交互之前,它不会检查它是否存在。也就是说,它不会抛出Exception
,而是抛出Error
:
// this doesn't exist!
use Foo/Bar;
try {
$instanceOfBar = new Bar();
}
catch (Error $e) {
// catching an Exception will not work
// Throwable or Error will work
}
您可以在运行时捕获和检查不存在的类,但在您这样做之前,它会很乐意折腾引用不存在的类的字符串。
对于 Laravel 的 IoC 容器和自动加载器来说,这是一种祝福,它滥用它来将类别名为方便的顶级对象。一个诅咒,如果你期望PHP对不存在::class
大惊小怪。
更新:对于担心此问题的人,我的建议是在测试管道中使用PHPStan。它可以防止很多错误,并且与php -l
不同的是,如果您要尝试与不存在的类进行交互,它将捕获。
据我所知,当您尝试实例化无法通过自动加载或显式添加找到的类时,您将收到一条很好的错误消息。
如果要检查该类是否存在,首先,请尝试以下操作:
$classOutsideNamespaceExists = class_exists('Bar');
$classInsideNameSpaceExists = class_exists('\Foo\Bar'));
或者你可以试试这个从 PHP 5.5 开始可用的语法:
class_exists(MyClass::class)
最后,您始终可以使用 try-catch 块的 try 和 true 方法。
try {
$instanceOfMyClass = new MyClass();
}
catch (Exception $e) {
// conclude the class does not exist and handle accordingly
}
PhpStorm 提出并生成提示,如
ArrayShape
、Pure
等。但它会自动添加
php use JetBrainsPhpStormArrayShape;
或其他。
在某些生产服务器上我会出错并不是那么危险 "Class JetBrains\PhpStorm\ArrayShape not found"?
(c)懒人:
-
好吧,只需使用作曲家要求--dev jetbrains/phpstorm-attributes将此类类添加到您的项目中。请参阅 github.com/JetBrains/phpstorm-attributes
-
只要此类的实例实际上没有被实例化(创建),就应该没有错误,因为 use 语句只是一个声明。