PHP'使用'关键字如何工作(在Symfony 2中)?

时间:2015-03-30 19:58:57

标签: php symfony namespaces

在Symfony 2中,所有请求都通过app_dev.php(或app.php)进行路由。

前几行看起来像:

<?php

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Debug\Debug;
...

理论上,我认为这只是将指定的命名空间(或类)导入当前范围。我不明白的是PHP如何将其映射到文件。例如,Debug类位于:

vendor/symfony/symfony/src/Symfony/Component/Debug/Debug.php

PHP如何知道查看vendor/symfony/symfony/src/

我可能误解了正在发生的事情,但任何澄清都会受到赞赏。

2 个答案:

答案 0 :(得分:3)

知道一个类所在的文件不是语言的工作,它是自动加载器的工作。

所有use关键字都是这个实例创建别名:

use Symfony\Component\HttpFoundation\Request;

这在以下脚本中说,当我引用Request时,我确实意味着Symfony\Component\HttpFoundation\Request。如果我以某种方式使用Request对象(通过创建实例或在其上调用静态方法),那么自动加载器将尝试加载已定义类的文件(如果尚未加载)

然而,自动加载器的内部工作方式因项目而异。已经采取行动标准化自动加载器行为àla PSR-4,但语言中没有任何内容表明您必须遵守该标准。例如,你可以有一个方案,其中所有类文件都驻留在一个目录中,你的自动加载器只是从那里加载所有类,无论它们在哪个命名空间。

这个计划会受到这样一个事实的影响,即每个名字只能有一个类,但没有什么能阻止你这样做。

回答你的问题:“它如何知道”Symfony \ Component \ Debug \ Debug“是一个有效的命名空间?”

它没有,因为它实际上并没有出去并试图在此时加载该类。如果在任何随机的PHP脚本中你把这样的东西放在顶部:

use \Non\Existant\ObjectClass;

但是,不要在任何地方实际使用 ObjectClass,您将不会遇到任何错误。但是,如果您尝试说new ObjectClass,则会出现类未找到错误。

答案 1 :(得分:0)

简单地说,您必须事先将所有文件加载到PHP的内存中。 PHP本身并没有任何标准来定位文件,加载文件的规则必须由你的代码完成。

当PHP尝试加载文件时,如果类定义存在,它将检查其内存,如果不存在,它将尝试自动加载可能包含类定义的文件;请参阅PHP: Autoloading Classesspl_autoload_register

PHP Framework Interop Group

定义了一些常见的自动加载策略
  • PSR-0(自动加载标准)
  • PSR-4(改进的自动加载标准)

在这种情况下,自动加载由Composer完成,您需要做的就是在任何脚本中包含vendor/autoload.php,并且可以自动加载通过composer下载的供应商代码。您也可以手动将类添加到composer自动加载器中。请参阅:Composer Autoloading