参考链接

PSR0

规范

As of 2014-10-21 PSR-0 has been marked as deprecated. PSR-4 is now recommended as an alternative. 截至2014年10月21日,PSR-0已标记为弃用。现在推荐PSR-4作为替代方案。

如果要通过自动加载器(autoloader),要遵守以下规定

  • 一个完全标准的命名空间(namespace)类(class)的结构是这样的:\<Vendor Name>\(<Namespace>\)*<Class Name>
  • 每个命名空间(namespace)都必须有一个顶级的空间名(namespace)(“组织名(Vendor Name)“)。
  • 每个命名空间(namespace)中可以根据需要使用任意数量的子命名空间(sub-namespace)
  • 从文件系统中加载源文件时,空间名(namespace)中的分隔符将被转换为 DIRECTORY_SEPARATOR
  • 类名(class name)中的每个下划线_都将被转换为一个DIRECTORY_SEPARATOR。下划线_空间名(namespace)中没有什么特殊的意义。
  • 完全标准的命名空间(namespace)类(class)从文件系统加载源文件时将会加上.php后缀。
  • 组织名(vendor name)空间名(namespace)类名(class name)都由大小写字母组合而成。

举例

  • \Doctrine\Common\IsolatedClassLoader => /path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php
  • \Symfony\Core\Request => /path/to/project/lib/vendor/Symfony/Core/Request.php
  • \Zend\Acl => /path/to/project/lib/vendor/Zend/Acl.php
  • \Zend\Mail\Message => /path/to/project/lib/vendor/Zend/Mail/Message.php

下划线举例

  • \namespace\package\Class_Name => /path/to/project/lib/vendor/namespace/package/Class/Name.php
  • \namespace\package_name\Class_Name => /path/to/project/lib/vendor/namespace/package_name/Class/Name.php

实现

  1. function autoload($className)
  2. {
  3. $className = ltrim($className, '\\');
  4. $fileName = '';
  5. $namespace = '';
  6. if ($lastNsPos = strrpos($className, '\\')) {
  7. $namespace = substr($className, 0, $lastNsPos);
  8. $className = substr($className, $lastNsPos + 1);
  9. $fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
  10. }
  11. $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
  12. require $fileName;
  13. }
  14. spl_autoload_register('autoload');

PSR4

规范

这个 PSR 描述的是通过文件路径 自动载入 类的指南;它作为对 PSR-0 的补充;根据这个 指导如何规范存放文件来自动载入;

  1. 术语「类」是一个泛称;它包含类,接口,traits 以及其他类似的结构;
  2. 完全限定类名应该类似如下范例:
    ()*
    1. 完全限定类名必须有一个顶级命名空间(Vendor Name);
    2. 完全限定类名可以有多个子命名空间;
    3. 完全限定类名应该有一个终止类名;
    4. 下划线在完全限定类名中是没有特殊含义的;
    5. 字母在完全限定类名中可以是任何大小写的组合;
    6. 所有类名必须以大小写敏感的方式引用;
  3. 当从完全限定类名载入文件时:
    1. 在完全限定类名中,连续的一个或几个子命名空间构成的命名空间前缀(不包括顶级命名空间的分隔符),至少对应着至少一个基础目录。
    2. 在「命名空间前缀」后的连续子命名空间名称对应一个「基础目录」下的子目录,其中的命名 空间分隔符表示目录分隔符。子目录名称必须和子命名空间名大小写匹配;
    3. 终止类名对应一个以 .php 结尾的文件。文件名必须和终止类名大小写匹配;
  4. 自动载入器的实现不可抛出任何异常,不可引发任何等级的错误;也不应返回值;

举例

FULLY QUALIFIED CLASS NAME NAMESPACE PREFIX BASE DIRECTORY RESULTING FILE PATH
\Acme\Log\Writer\File_Writer Acme\Log\Writer ./acme-log-writer/lib/ ./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\Status Aura\Web /path/to/aura-web/src/ /path/to/aura-web/src/Response/Status.php
\Symfony\Core\Request Symfony\Core ./vendor/Symfony/Core/ ./vendor/Symfony/Core/Request.php
\Zend\Acl Zend /usr/includes/Zend/ /usr/includes/Zend/Acl.php