FormBuilder
由于命名空间,自动加载在寻找实现时不会找到Form
类的MySweetForms
实现,前提是自动加载器和两个库遵循最佳(或接近最佳)实践并正确实现。
如果MySweetForms/AjaxFileField.php
文件在命名空间内定义了一个类,MySweetForms
如下所示:
namespace MySweetForms;
class AjaxFileField
{
public function doFormStuff()
{
$form = new Form();
}
}
那么Form
里面类的引用AjaxFileField
其实就是全限定类名的简写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
(此时它将Form.php
直接在lib
文件夹内的文件中查找)。
关键是要认识到实际上并没有两个Form
类——一个类的完全限定名是FormBuilder\Core\Form
,一个类的完全限定名是MySweetForms\Form
——并且正确实施的自动加载器会期望它们位于完全不同的位置,不会尝试加载一个文件来代替另一个文件。
命名空间和基于命名空间将文件组织到目录中的 PSR 风格相结合,使得在不引起冲突的情况下重用常用词变得非常容易,并将完全限定的类名可预测地映射到相应的文件。
将类名解析为完全限定的类名是这一点的关键,并在 PHP 手册中进行了讨论(命名空间常见问题解答有几点关于它:http://www.php.net/manual/en/language。命名空间.faq.php)。PSR-0 标准本身也是一个有用的参考:https ://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md