PHP PSR-4 Autoloader 自动加载(中文版)

一、PSR0简介
下文描述了若要使用一个通用的自动加载器(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)都由大小写字母组合而成。

参考:http://www.php-fig.org/psr/psr-0/


以下,列出PSR0构建的规范类的几种形式:

二、实现PSR0自动加载

function autoload($className)
{
    $className = ltrim($className, '\\');
    $fileName  = '';
    $namespace = '';
    if ($lastNsPos = strrpos($className, '\\')) {
        $namespace = substr($className, 0, $lastNsPos);
        $className = substr($className, $lastNsPos + 1);
        $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
    }
    $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
 
    require $fileName;
}
spl_autoload_register('autoload');

 

三、PSR4简介
这个 PSR 描述的是通过文件路径自动载入类的指南;它作为对 PSR-0 的补充;根据这个 指导如何规范存放文件来自动载入;
术语「类」是一个泛称;它包含类,接口,traits 以及其他类似的结构;

完全限定类名应该类似如下范例:

<NamespaceName>(<SubNamespaceNames>)*<ClassName>

完全限定类名必须有一个顶级命名空间(Vendor Name);
完全限定类名可以有多个子命名空间;
完全限定类名应该有一个终止类名;
下划线在完全限定类名中是没有特殊含义的;
字母在完全限定类名中可以是任何大小写的组合;
所有类名必须以大小写敏感的方式引用;
当从完全限定类名载入文件时:

在完全限定类名中,连续的一个或几个子命名空间构成的命名空间前缀(不包括顶级命名空间的分隔符),至少对应着至少一个基础目录。
在「命名空间前缀」后的连续子命名空间名称对应一个「基础目录」下的子目录,其中的命名 空间分隔符表示目录分隔符。子目录名称必须和子命名空间名大小写匹配;
终止类名对应一个以 .php 结尾的文件。文件名必须和终止类名大小写匹配;
自动载入器的实现不可抛出任何异常,不可引发任何等级的错误;也不应返回值;

参考:http://www.php-fig.org/psr/psr-4/
在其中有以下的类实例,但是相对与PSR0,却是不太容易明白

首先,\Symfony\Core\Request和\Zend\Acl很好理解,其满足PSR0规范,但是\Acme\Log\Writer\File_Writer就不太好理解了。


四、Composer对PSR4的处理
看了Composer对PSR4的处理,才能比较容易理解PSR4。自动生成的PSR4配置文件名称为autoload_psr4.php(PSR0的是autoload_namespace.php),配置文件返回一个关联数组,键是名称空间的前缀,值是名称空间前缀对应的路径。

以\Acme\Log\Writer\File_Writer作为例子,其名称空间前缀是\Acme\Log\Writer,则其在autoload_psr4.php表示为
'\<span style="font-size:14px;">\Acme\\Log\\Writer</span>' => (array) './acme-log-writer/lib/'
使用自动加载时,先通过名称空间的前缀,找到对应的映射路径,在根据PSR0规范找到对应的类定义文件。但是这里有些例外,类名中的下划线在PSR4中是不需要转换成目录的。

使用PSR4,我觉得有2个好处:
1. 减少代码目录的深度
2. 可以通过前缀快速找到映射目录,提高自动加载的效率

 

Autoloader

关键词 “必须”("MUST")、“一定不可/一定不能”("MUST NOT")、“需要”("REQUIRED")、

“将会”("SHALL")、“不会”("SHALL NOT")、“应该”("SHOULD")、“不该”("SHOULD NOT")、

“推荐”("RECOMMENDED")、“可以”("MAY")和”可选“("OPTIONAL")的详细描述可参见 [RFC 2119][] 。

 

1. 概述

本 PSR 是关于由文件路径 自动载入 对应类的相关规范,

本规范是可互操作的,可以作为任一自动载入规范的补充,其中包括 PSR-0,此外,

本 PSR 还包括自动载入的类对应的文件存放路径规范。

 

2. 详细说明

此处的“类”泛指所有的class类、接口、traits可复用代码块以及其它类似结构。

一个完整的类名需具有以下结构:

\<命名空间>(\<子命名空间>)*\<类名>

完整的类名必须要有一个顶级命名空间,被称为 "vendor namespace";

完整的类名可以有一个或多个子命名空间;

完整的类名必须有一个最终的类名;

完整的类名中任意一部分中的下滑线都是没有特殊含义的;

完整的类名可以由任意大小写字母组成;

所有类名都必须是大小写敏感的。

当根据完整的类名载入相应的文件……

完整的类名中,去掉最前面的命名空间分隔符,前面连续的一个或多个命名空间和子命名空间,作为“命名空间前缀”,其必须与至少一个“文件基目录”相对应;

紧接命名空间前缀后的子命名空间必须与相应的”文件基目录“相匹配,其中的命名空间分隔符将作为目录分隔符。

末尾的类名必须与对应的以 .php 为后缀的文件同名。

自动加载器(autoloader)的实现一定不能抛出异常、一定不能触发任一级别的错误信息以及不应该有返回值。
 

3. 例子

下表展示了符合规范完整类名、命名空间前缀和文件基目录所对应的文件路径。

blob.png

 

注意:实例并不属于规范的一部分,且随时会有所变动。

修改时间 2018-09-20

真诚赞赏,手留余香
赞赏
随机推荐
axios发送post请求,nodejs无法正常获取
windows mysql 自动备份的几种方法
我眼中的前端框架jQuery,Angular,React,Vue——以及我看前端架构
微信开发示例(图片信息的发送)
怪异模式(Quirks Mode)导致 button 和 input 的大小不统一原因
使用Keytools生成安卓证书
使用 linear-gradient 创建渐变背景色的背景
MacOS launchctl 启动进程控制
macOS安装composer
CentOS 8 使用防火墙限制每个 IP 的最大连接数