使用关键字“使用”有条件地导入类
Posted
技术标签:
【中文标题】使用关键字“使用”有条件地导入类【英文标题】:Import class conditionally with the keyword 'use' 【发布时间】:2014-09-15 17:56:47 【问题描述】:我从未在任何地方见过这种结构,所以我想知道这样的表达式是否有问题:
if (condition)
use Symfony\Component\HttpFoundation\Response;
【问题讨论】:
你为什么需要它? 使用条件的目的是什么?use
不包括任何东西。
根据文档the importing is done at compile time and not runtime
,所以你不应该这样做。 php.net/manual/en/language.namespaces.importing.php
看这个 php.net There is a similar demo about namespace usage.
这个想法是为了避免加载不必要的代码,所以我认为@Debflav 解释了它。
【参考方案1】:
use
唯一要做的就是别名一个类名。而已。仅此而已。
不必在脚本中重复编写完全限定的类名:
$q = new \Foo\Bar\Baz\Quux;
if ($q instanceof \Foo\Bar\Baz\Quux) ...
您可以将其缩短为:
use Foo\Bar\Baz\Quux;
$q = new Quux;
if ($q instanceof Quux) ...
因此,想要有条件地使用use
绝对没有意义。它只是一个语法助手;如果可以有条件地使用它,您的 脚本语法 会变得模棱两可,这是没有人想要的。
它不会减少代码加载,因为代码只能通过require
/include
调用或通过自动加载显式加载。后者是非常受欢迎的,因为它已经懒惰地只在需要时才开始行动。
【讨论】:
这是有道理的。假设我正在为后端 API 更换供应商。我希望能够从使用一个客户端切换到另一个客户端,而无需编写大量代码来进行切换。假设我在环境变量中定义 API 供应商:VENDOR=SignalWire
或 VENDOR=Twilio
在设置客户端连接的类中,我想初始化“正确的客户端”。加载正确供应商代码的条件使用将是完美的,然后我不必在可能有几十个“新”的其余代码中有条件地使用类。
切换不应该发生在切换出类名的级别!你的一段代码应该清楚地知道两个不同的类名,然后有意识地实例化一个,然后你就可以传递一个或另一个类的实例。这就是正确的 OOP 多态性。
是的,你是对的。我最终解决这个问题的方法是使用 ClassA 作为 Foo;使用 ClassB 作为 Bar;然后根据环境有条件地返回正确实例化的类。
是的。这是正确方法的另一个原因是构造函数可能非常不同。即使类的接口相同且可互换,但如果它们需要不同的构造函数参数,您的代码中的 something 需要清楚地知道哪个类是哪个,并且不能让 PHP 进行切换在句法层面。【参考方案2】:
这将引发语法错误。来自 TFM:
use
关键字必须在文件的最外层范围内声明 (全局范围)或内部命名空间声明。这是因为 导入是在编译时而不是运行时完成的,所以它不能 块作用域。
【讨论】:
以上是关于使用关键字“使用”有条件地导入类的主要内容,如果未能解决你的问题,请参考以下文章