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

How does the PHP 'use' keyword work (in Symfony 2)?

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

前几行看起来像:

<?php

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

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

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

PHP 怎么知道要在 vendor/symfony/symfony/src/ 中查找?

我可能误解了发生的事情,但如有任何澄清,我们将不胜感激。

知道 class 所在的文件不是语言的工作,而是自动加载器的工作。

use 关键字所做的就是此实例创建一个别名:

use Symfony\Component\HttpFoundation\Request;

这是在下面的脚本中说的,当我提到 Request 时,我 真的 是指 Symfony\Component\HttpFoundation\Request。如果我以某种方式使用 Request 对象(通过创建实例或在其上调用静态方法),那么自动加载器将去尝试加载 class 定义的文件,如果它没有'尚未加载。

不过,自动加载器的内部工作原理因项目而异。自动加载器行为标准化 à la PSR-4,但语言中没有任何内容表明您必须遵守该标准。例如,你可以有一个方案,其中 all class 文件驻留在一个目录中,而你的自动加载器只从那里加载所有 classes,不管是什么他们所在的命名空间。

每个名字只能有一个 class 这一事实会影响该方案,但没有什么能阻止您这样做。

回答您的问题:"How does it know that "Symfony\Component\Debug\Debug" 是一个有效的命名空间吗?"

它没有,因为此时它实际上并没有出去并试图加载 class。如果在任何随机 PHP 脚本中,您将类似这样的内容放在顶部:

use \Non\Existant\ObjectClass;

但实际上永远不要在任何地方使用 ObjectClass,你不会得到任何错误。但是,如果您尝试说 new ObjectClass,您将收到 class not found 错误。

简单地说,您必须预先将所有文件加载到内存中 PHP。 PHP 对于文件所在的位置没有任何固有的标准,加载文件的规则必须由您的代码完成。

当 PHP 尝试加载文件时,如果 class 定义存在,它将检查其内存,如果不存在,它将尝试自动加载可能包含您的 class 的文件定义;见 PHP: Autoloading Classes and spl_autoload_register

PHP Framework Interop Group定义了一些常见的自动加载策略:

  • PSR-0(自动加载标准)
  • PSR-4(改进的自动加载标准)

在这种情况下,自动加载由 Composer, all you need to do is include vendor/autoload.php in any of your scripts and vendor code downloaded via composer can be autoloaded. You can manually add classes into the composer autoloader as well. See: Composer Autoloading

完成