在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/
?
我可能误解了正在发生的事情,但任何澄清都会受到赞赏。
答案 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 Classes和spl_autoload_register
定义了一些常见的自动加载策略在这种情况下,自动加载由Composer完成,您需要做的就是在任何脚本中包含vendor/autoload.php
,并且可以自动加载通过composer下载的供应商代码。您也可以手动将类添加到composer自动加载器中。请参阅:Composer Autoloading