gpt4 book ai didi

php - 为什么不使用命名空间进行自动加载不好的做法?

转载 作者:行者123 更新时间:2023-12-04 16:52:22 25 4
gpt4 key购买 nike

我看过很多使用 PSR 来自动加载命名空间的例子。也许这是一个愚蠢的问题,但为什么这不是不好的做法?这不会违背拥有命名空间的目的吗?

例如,假设您有两个库,FormBuilderMySweetForms ,并且都有一个 Form类(class)。地点在:
lib/FormBuilder/Core/Form.phplib/MySweetForms/Form.php
如果您基于命名空间自动加载那些 Form类在其中,您是否会遇到命名空间旨在防止的确切问题:类和方法的不明确标识符?

当你在MySweetForms中成功定位到另一个类时,它不会失败吗?命名空间,比如 AjaxFileField ,这依赖于 \MySweetForms\Form ,但它找到了 FormBuilder的实现 Form类(class)?

最佳答案

由于命名空间,自动加载将找不到 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类,但忽略提供 namespace ,实际类( 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.namespaces.faq.php)。 PSR-0 标准本身也是一个有用的引用: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md

关于php - 为什么不使用命名空间进行自动加载不好的做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17310088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com