PSR-4元文档

PSR-4元文档

1.总结

目的是为可互操作的PHP自动加载器指定规则,该自动加载器将名称空间映射到文件系统路径,并且可以与任何其他SPL注册的自动加载器共存。这将是PSR-0的补充,而不是替代PSR-0。

为什么要打扰?

PSR-0的历史

在PHP 5.2及之前的限制下,PSR-0类命名和自动加载标准在Horde / PEAR公约的广泛接受之后上升。根据该约定,趋势是将所有PHP源类放在单个主目录中,使用类名中的下划线来指示伪命名空间,如下所示:

/path/to/src/
    VendorFoo/
        Bar/
            Baz.php     # VendorFoo_Bar_Baz
    VendorDib/
        Zim/
            Gir.php     # Vendor_Dib_Zim_Gir

随着PHP 5.3的发布和命名空间的正确使用,PSR-0被引入以允许旧的Horde / PEAR下划线模式新的命名空间符号的使用。类名中仍然允许使用下划线,以简化从较旧的命名空间命名到较新命名的过渡,从而鼓励更广泛的采用。

/path/to/src/
    VendorFoo/
        Bar/
            Baz.php     # VendorFoo_Bar_Baz
    VendorDib/
        Zim/
            Gir.php     # VendorDib_Zim_Gir
    Irk_Operation/
        Impending_Doom/
            V1.php
            V2.php      # Irk_Operation\Impending_Doom\V2

PEAR安装程序将源文件从PEAR包移动到单个中央目录中,这一结构非常了解这一结构。

沿着Composer

使用Composer,包源不再复制到单个全局位置。它们从安装位置使用,不会移动。这意味着使用Composer,与PEAR一样,PHP源没有“单个主目录”。相反,有多个目录; 每个包都在每个项目的单独目录中。

为了满足PSR-0的要求,这会导致Composer包看起来像这样:

vendor/
    vendor_name/
        package_name/
            src/
                Vendor_Name/
                    Package_Name/
                        ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                Vendor_Name/
                    Package_Name/
                        ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

“src”和“tests”目录必须包含供应商和包目录名称。这是符合PSR-0标准的工件。

许多人发现这种结构比必要的更深刻,更重复。此提议建议添加或替代PSR将非常有用,以便我们可以使包含更像以下内容的包:

vendor/
    vendor_name/
        package_name/
            src/
                ClassName.php       # Vendor_Name\Package_Name\ClassName
            tests/
                ClassNameTest.php   # Vendor_Name\Package_Name\ClassNameTest

这将需要实现最初称为“面向包的自动加载”(与传统的“直接类到文件自动加载”)。

面向包的自动加载

通过对PSR-0的扩展或修改来实现面向包的自动加载很困难,因为PSR-0不允许类名的任何部分之间的代理路径。这意味着面向包的自动加载器的实现将比PSR-0更复杂。但是,它将允许更清洁的包装。

最初,建议遵循以下规则:

  1. 实现者必须至少使用两个命名空间级别:供应商名称和该供应商中的包名称。(此顶级双名组合在下文中称为供应商包名称或供应商包名称空间。)

  2. 实现者必须允许vendor-package命名空间和完全限定类名的其余部分之间的路径中缀。

  3. vendor-package命名空间可以映射到任何目录。完全限定类名的剩余部分必须将命名空间名称映射到具有相同名称的目录,并且必须将类名映射到以.php结尾的同名文件。

请注意,这意味着类名中下划线作为目录分隔符的结尾。人们可能会认为下划线应该受到尊重,因为它们属于PSR-0,但是看到它们在该文档中的存在是指从PHP 5.2和之前的伪命名空间过渡,也可以在这里删除它们。

3.范围

3.1目标

  • 保留PSR-0规则,实现者必须至少使用两个命名空间级别:供应商名称和该供应商中的包名称。

  • 允许vendor-package命名空间与完全限定类名的其余部分之间的路径中缀。

  • 允许vendor-package命名空间MAY映射到任何目录,可能是多个目录。

  • 结束将类名称中的下划线作为目录分隔符

3.2非目标

  • 为非类资源提供通用转换算法

4.方法

4.1选择方法

这种方法保留了PSR-0的关键特性,同时消除了它所需的更深层的目录结构。此外,它还指定了某些其他规则,这些规则使实现明确地更具互操作性。

尽管与目录映射无关,但最终草案还指定了自动加载器应如何处理错误。具体来说,它禁止抛出异常或引发错误。原因是双重的。

  1. PHP中的自动加载器明确设计为可堆叠,因此如果一个自动加载器无法加载类,则另一个自动加载器有机会这样做。让自动装带器触发断开错误条件会违反该兼容性。

  2. class_exists()并且interface_exists()允许“即使在尝试自动加载后也未找到”作为合法的正常用例。抛出异常的自动加载器会导致class_exists()无法使用,从互操作性的角度来看,这是完全不可接受的。希望在类未找到的情况下提供额外调试信息的自动加载器应该通过日志记录来执行此操作,或者使用PSR-3兼容的记录器或其他方式。

优点:

  • 浅层目录结构

  • 更灵活的文件位置

  • 阻止类名中的下划线被视为目录分隔符

  • 使实现更加明确地可互操作

缺点:

  • 在PSR-0下,不再可能只检查一个类名来确定它在文件系统中的位置(从Horde / PEAR继承的“类到文件”约定)。

4.2替代方案:仅限PSR-0

仅使用PSR-0虽然合理,但确实给我们留下了相对较深的目录结构。

优点:

  • 无需改变任何人的习惯或实施

缺点:

  • 让我们有更深入的目录结构

  • 给我们留下类名中的下划线作为目录分隔符

4.3替代方案:拆分自动加载和转换

Beau Simensen和其他人建议转换算法可能会从自动加载提案中分离出来,以便转换规则可以被其他提案引用。在完成将它们分开,然后进行民意调查和一些讨论之后,组合版本(即自动加载器提议中嵌入的转换规则)被显示为首选项。

优点:

  • 转换规则可以由其他提案单独引用

缺点:

  • 不符合民意调查受访者和一些合作者的意愿

4.4替代方案:使用更多命令式和叙事性语言

在多个+1选民听到他们支持这个想法但未同意(或理解)提案的措辞后,赞助商撤回了第二次投票后,有一段时间,投票通过的提案得到了扩展。更大的叙事和更有必要的语言。少数参与者谴责这种方法。过了一段时间,Beau Simensen开始进行实验性修订,着眼于PSR-0; 编辑和赞助商赞成采用这种更简洁的方法,并指导现在正在考虑的版本,由Paul M. Jones编写并为许多人做出贡献。

与PHP 5.3.2及更低版本的兼容性说明

5.3.3之前的PHP版本不会删除前导命名空间分隔符,因此需要注意的是实现。无法删除前导命名空间分隔符可能会导致意外行为。

5.人

5.1编辑

  • Paul M. Jones,Solar / Aura

5.2赞助商

  • Phil Sturgeon,PyroCMS(协调员)
  • 拉里加菲尔德,Drupal

5.3贡献者

  • 安德烈亚斯亨宁斯
  • 伯恩哈德施塞克
  • Beau Simensen
  • 唐纳德吉尔伯特
  • 迈克范瑞尔
  • Paul Dragoonis
  • 太多其他人的名字和数量

6.投票