PHP';使用';关键字工作(在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;
...

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

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

PHP如何知道在vendor/symfony/symfony/src/中查找?

我可能误解了正在发生的事情,但任何澄清都将不胜感激。

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

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

use Symfony'Component'HttpFoundation'Request;

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

不过,自动加载器的内部工作方式因项目而异。已经有了一项标准化自动加载器行为的举措àlaPSR-4,但语言中没有任何内容表明你必须遵守该标准。例如,你可以有一个方案,所有类文件都位于一个目录中,而你的自动加载器只从那里加载所有类,而不管它们在哪个命名空间中。

这种方案会受到这样一个事实的影响,即每个名称只能有一个类,但没有什么可以阻止你这样做。

要回答您的问题:"它怎么知道"Symfony''Component''Debug''Debug"是一个有效的命名空间?"

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

use 'Non'Existant'ObjectClass;

但永远不要在任何地方使用ObjectClass,你不会得到任何错误。但是,如果您尝试说new ObjectClass,您将得到一个未找到类的错误。

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

当PHP试图加载一个文件时,它会检查内存中是否存在类定义,如果不存在,它会尝试自动加载可能包含类定义的文件;请参阅PHP:自动加载类和spl_autoload_register

PHP框架互操作组定义了一些常见的自动加载策略:

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

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