PSR-4 自动加载规范 - 说明文档
PSR-4 是为了给可交互的 PHP 自动加载器指定一个将命名空间映射到文件系统的规则，并且可以与其他 SPL 注册的自动加载器共存。PSR-4 不是 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 时 PHP 资源不像 PEAR 一样有「单一主目录」。取而代之的是多个目录；每个项目的每个包都在单独目录中。
为了符合 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
It's difficult to implement package-oriented autoloading via an extension or amendment to PSR-0, because PSR-0 does not allow for an intercessory path between any portions of the class name. This means the implementation of a package-oriented autoloader would be more complicated than PSR-0. However, it would allow for cleaner packages.
Initially, the following rules were suggested:
Implementors MUST use at least two namespace levels: a vendor name, and package name within that vendor. (This top-level two-name combination is hereinafter referred to as the vendor-package name or the vendor-package namespace.)
Implementors MUST allow a path infix between the vendor-package namespace and the remainder of the fully qualified class name.
- The vendor-package namespace MAY map to any directory. The remaining portion of the fully-qualified class name MUST map the namespace names to identically-named directories, and MUST map the class name to an identically-named file ending in .php.
Note that this means the end of underscore-as-directory-separator in the class name. One might think underscores should be honored as they are under PSR-0, but seeing as their presence in that document is in reference to transitioning away from PHP 5.2 and previous pseudo-namespacing, it is acceptable to remove them here as well.
Retain the PSR-0 rule that implementors MUST use at least two namespace levels: a vendor name, and package name within that vendor.
Allow a path infix between the vendor-package namespace and the remainder of the fully qualified class name.
Allow the vendor-package namespace MAY map to any directory, perhaps multiple directories.
- End the honoring of underscores in class names as directory separators
- Provide a general transformation algorithm for non-class resources
4.1 Chosen Approach
This approach retains key characteristics of PSR-0 while eliminating the deeper directory structures it requires. In addition, it specifies certain additional rules that make implementations explicitly more interoperable.
Although not related to directory mapping, the final draft also specifies how autoloaders should handle errors. Specifically, it forbids throwing exceptions or raising errors. The reason is two-fold.
Autoloaders in PHP are explicitly designed to be stackable so that if one autoloader cannot load a class another has a chance to do so. Having an autoloader trigger a breaking error condition violates that compatibility.
interface_exists()allow "not found, even after trying to autoload" as a legitimate, normal use case. An autoloader that throws exceptions renders
class_exists()unusable, which is entirely unacceptable from an interoperability standpoint. Autoloaders that wish to provide additional debugging information in a class-not-found case should do so via logging instead, either to a PSR-3 compatible logger or otherwise.
Shallower directory structures
More flexible file locations
Stops underscore in class name from being honored as directory separator
- Makes implementations more explicitly interoperable
- It is no longer possible, as under PSR-0, to merely examine a class name to determine where it is in the file system (the "class-to-file" convention inherited from Horde/PEAR).
4.2 Alternative: Stay With PSR-0 Only
Staying with PSR-0 only, although reasonable, does leave us with relatively deeper directory structures.
- No need to change anyone's habits or implementations
Leaves us with deeper directory structures
- Leaves us with underscores in the class name being honored as directory separators
4.3 Alternative: Split Up Autoloading And Transformation
Beau Simensen and others suggested that the transformation algorithm might be split out from the autoloading proposal so that the transformation rules could be referenced by other proposals. After doing the work to separate them, followed by a poll and some discussion, the combined version (i.e., transformation rules embedded in the autoloader proposal) was revealed as the preference.
- Transformation rules could be referenced separately by other proposals
- Not in line with the wishes of poll respondents and some collaborators
4.4 Alternative: Use More Imperative And Narrative Language
After the second vote was pulled by a Sponsor after hearing from multiple +1 voters that they supported the idea but did not agree with (or understand) the wording of the proposal, there was a period during which the voted-on proposal was expanded with greater narrative and somewhat more imperative language. This approach was decried by a vocal minority of participants. After some time, Beau Simensen started an experimental revision with an eye to PSR-0; the Editor and Sponsors favored this more terse approach and shepherded the version now under consideration, written by Paul M. Jones and contributed to by many.
Compatibility Note with PHP 5.3.2 and below
PHP versions before 5.3.3 do not strip the leading namespace separator, so the responsibility to look out for this falls on the implementation. Failing to strip the leading namespace separator could lead to unexpected behavior.
- Paul M. Jones, Solar/Aura
- Phil Sturgeon, PyroCMS (Coordinator)
- Larry Garfield, Drupal
- Andreas Hennings
- Bernhard Schussek
- Beau Simensen
- Donald Gilbert
- Mike van Riel
- Paul Dragoonis
- Too many others to name and count
1st attempt: https://groups.google.com/forum/#!topic/php-fig/Ua46E344_Ls, presented prior to new workflow; aborted due to accidental proposal modification
2nd attempt: https://groups.google.com/forum/#!topic/php-fig/NWfyAeF7Psk, cancelled at the discretion of the sponsor https://groups.google.com/forum/#!topic/php-fig/t4mW2TQF7iE
- 3rd attempt: TBD
7. Relevant Links
- Autoloader, round 4
- POLL: Autoloader: Split or Combined?
- PSR-X autoloader spec: Loopholes, ambiguities
- Autoloader: Combine Proposals?
- Package-Oriented Autoloader, Round 2
- Autoloader: looking again at namespace
- DISCUSSION: Package-Oriented Autoloader - vote against
- VOTE: Package-Oriented Autoloader
- Proposal: Package-Oriented Autoloader
- Towards a Package Oriented Autoloader
- List of Alternative PSR-4 Proposals
- Summary of [post-Acceptance Vote pull] PSR-4 discussions
我们的翻译工作遵照 CC 协议，如果我们的工作有侵犯到您的权益，请及时联系我们。