由于命名空间,自动加载在寻找MySweetForms 实现时将找不到FormBuilder 的Form 类实现,前提是自动加载器和两个库遵循最佳(或接近最佳) ) 实践并正确实施。
如果MySweetForms/AjaxFileField.php 文件在MySweetForms 命名空间内定义了一个类,如图所示:
namespace MySweetForms;
class AjaxFileField
{
public function doFormStuff()
{
$form = new Form();
}
}
那么AjaxFileField 内部对Form 类的引用实际上是完全限定类名MySweetForms\Form 的简写。
当调用自动加载器来加载类时,它会被要求根据它的完全限定名称来加载类。 PSR-0 自动加载器会将MySweetForms\Form 类名转换为MySweetForms/Form.php 路径,并且(假设它被告知在lib 目录中查找)它会找到指向正确文件的方法。如果该文件丢失,自动加载器最终会失败。类似地,如果该文件定义了一个 Form 类但忽略了提供命名空间,则实际类 (MySweetForms\Form) 将不存在(相反,全局类 Form 将)——这与完全限定名称不匹配AjaxFileField 类中引用的类,所以会发生错误。
请注意,如果代码包含 $form = new \FormBuilder\Core\Form();,则类名已经是完全限定的,并且会要求自动加载器加载 FormBuilder\Core\Form 类(并希望它在 FormBuilder/Core/Form.php 文件中) .
如果我们使用了$form = new \Form();,我们将引用全局命名空间中的Form 类,并且自动加载器将被要求查找Form(它会直接在@987654346 内的Form.php 文件中查找@ 文件夹)。
关键是要认识到实际上没有两个Form 类——一个类的完全限定名称为FormBuilder\Core\Form,一个类的完全限定名称为MySweetForms\Form——和一个正确实施的自动加载器会期望它们位于完全不同的位置,并且不会尝试加载一个文件来代替另一个文件。
命名空间和基于命名空间将文件组织到目录中的 PSR 风格相结合,可以很容易地重复使用常用词而不会引起冲突,并将完全限定的类名可预测地映射到相应的文件。
将类名解析为完全限定的类名是这一点的关键,并在 PHP 手册中进行了讨论(命名空间常见问题解答有几点:http://www.php.net/manual/en/language.namespaces.faq.php)。 PSR-0 标准本身也是一个有用的参考:https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md