PSR-4 的实现示例
闭包实例
<?php
/**
* 一个具体项目实现的示例。
*
* 在注册自动加载函数后,下面这行代码将引发程序
* 尝试从 /path/to/project/src/Baz/Qux.php
* 加载 \Foo\Bar\Baz\Qux 类:
*
* new \Foo\Bar\Baz\Qux;
*
* @param string $class 完全标准的类名。
* @return void
*/
spl_autoload_register(function ($class) { // 具体项目的命名空间前缀
$prefix = 'Foo\\Bar\\'; // 命名空间前缀对应的基础目录
$base_dir = __DIR__ . '/src/'; // 该类使用了此命名空间前缀?
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// 否,交给下一个已注册的自动加载函数
return;
} // 获取相对类名
$relative_class = substr($class, $len); // 命名空间前缀替换为基础目录,
// 将相对类名中命名空间分隔符替换为目录分隔符,
// 附加 .php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; // 如果文件存在,加载它
if (file_exists($file)) {
require $file;
}
});
类实例
<?php
namespace Example; /**
* 一个多用途的示例实现,包括了
* 允许多个基本目录用于单个
* 命名空间前缀的可选功能
*
* 下述示例给出了一个 foo-bar 类包,系统中路径结构如下……
*
* /path/to/packages/foo-bar/
* src/
* Baz.php # Foo\Bar\Baz
* Qux/
* Quux.php # Foo\Bar\Qux\Quux
* tests/
* BazTest.php # Foo\Bar\BazTest
* Qux/
* QuuxTest.php # Foo\Bar\Qux\QuuxTest
*
* ……添加路径到 \Foo\Bar\ 命名空间前缀的类文件中
* 如下所示:
*
* <?php
* // 实例化加载器
* $loader = new \Example\Psr4AutoloaderClass;
*
* // 注册加载器
* $loader->register();
*
* // 为命名空间前缀注册基本路径
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
* $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
*
* 下述语句会让自动加载器尝试从
* /path/to/packages/foo-bar/src/Qux/Quux.php
* 中加载 \Foo\Bar\Qux\Quux 类
*
* <?php
* new \Foo\Bar\Qux\Quux;
*
* 下述语句会让自动加载器尝试从
* /path/to/packages/foo-bar/tests/Qux/QuuxTest.php
* 中加载 \Foo\Bar\Qux\QuuxTest 类:
*
* <?php
* new \Foo\Bar\Qux\QuuxTest;
*/
class Psr4AutoloaderClass
{
/**
* 关联数组,键名为命名空间前缀,键值为一个基本目录数组。
*
* @var array
*/
protected $prefixes = array(); /**
* 通过 SPL 自动加载器栈注册加载器
*
* @return void
*/
public function register()
{
spl_autoload_register(array($this, 'loadClass'));
} /**
* 为命名空间前缀添加一个基本目录
*
* @param string $prefix 命名空间前缀。
* @param string $base_dir 命名空间下类文件的基本目录
* @param bool $prepend 如果为真,预先将基本目录入栈
* 而不是后续追加;这将使得它会被首先搜索到。
* @return void
*/
public function addNamespace($prefix, $base_dir, $prepend = false)
{
// 规范化命名空间前缀
$prefix = trim($prefix, '\\') . '\\'; // 规范化尾部文件分隔符
$base_dir = rtrim($base_dir, DIRECTORY_SEPARATOR) . '/'; // 初始化命名空间前缀数组
if (isset($this->prefixes[$prefix]) === false) {
$this->prefixes[$prefix] = array();
} // 保留命名空间前缀的基本目录
if ($prepend) {
array_unshift($this->prefixes[$prefix], $base_dir);
} else {
array_push($this->prefixes[$prefix], $base_dir);
}
} /**
* 加载给定类名的类文件
*
* @param string $class 合法类名
* @return mixed 成功时为已映射文件名,失败则为 false
*/
public function loadClass($class)
{
// 当前命名空间前缀
$prefix = $class; // 通过完整的命名空间类名反向映射文件名
while (false !== $pos = strrpos($prefix, '\\')) { // 在前缀中保留命名空间分隔符
$prefix = substr($class, 0, $pos + 1); // 其余的是相关类名
$relative_class = substr($class, $pos + 1); // 尝试为前缀和相关类加载映射文件
$mapped_file = $this->loadMappedFile($prefix, $relative_class);
if ($mapped_file) {
return $mapped_file;
} // 删除 strrpos() 下一次迭代的尾部命名空间分隔符
$prefix = rtrim($prefix, '\\');
} // 找不到映射文件
return false;
} /**
* 为命名空间前缀和相关类加载映射文件。
*
* @param string $prefix 命名空间前缀
* @param string $relative_class 相关类
* @return mixed Boolean 无映射文件则为false,否则加载映射文件
*/
protected function loadMappedFile($prefix, $relative_class)
{
// 命名空间前缀是否存在任何基本目录
if (isset($this->prefixes[$prefix]) === false) {
return false;
} // 通过基本目录查找命名空间前缀
foreach ($this->prefixes[$prefix] as $base_dir) { // 用基本目录替换命名空间前缀
// 用目录分隔符替换命名空间分隔符
// 给相关的类名增加 .php 后缀
$file = $base_dir
. str_replace('\\', '/', $relative_class)
. '.php'; // 如果映射文件存在,则引入
if ($this->requireFile($file)) {
// 搞定了
return $file;
}
} // 找不到
return false;
} /**
* 如果文件存在从系统中引入进来
*
* @param string $file 引入文件
* @return bool 文件存在则 true 否则 false
*/
protected function requireFile($file)
{
if (file_exists($file)) {
require $file;
return true;
}
return false;
}
}
PSR-4 的实现示例的更多相关文章
- PHP的PSR系列规范都有啥内容
PSR 是PHP Standard Recommendation的简写,它其实应该叫PSRs,即系列推荐标准:目前通过的规范有PSR-0(Autoloading Standard).PSR-1(Bas ...
- nginx subrequest演示示例程序
只有简单subrequest应用演示示例. nginx.conf文件: #user nobody; worker_processes 1; #error_log logs/error.log; #er ...
- PHP PSR 代码风格
FIG组织在制定跟PHP相关规范,简称PSR,PSR旨在通过讨论我们代码项目的共同点以找出一个协作编程的方法. 什么是psr0 强调自动加载的方式 下文描述了若要使用一个通用的自动加载器(autolo ...
- [转帖]Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍
Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍 原文:http://blog.csdn.net/tianlesoftware/article/details/58095 ...
- PSR规范0-4整理
PSR规范 psr规范 引言: PSR 是 PHP Standard Recommendations 的简写,由 PHP FIG 组织制定的 PHP 规范,是 PHP 开发的实践标准.这些规范的目的是 ...
- php开发规范-psr系列规范
转自:http://www.cnblogs.com/x3d/p/php-psr-standards.html PSR 是PHP Standard Recommendation的简写,它其实应该叫PSR ...
- ps示例
博客PS示例 一显示指定真正用户名(RUID)或用户ID的进程 打开另外一个终端 [root@centos72 ~]# id wang uid=1000(wang) gid=1000(wang) gr ...
- Swift3.0服务端开发(一) 完整示例概述及Perfect环境搭建与配置(服务端+iOS端)
本篇博客算是一个开头,接下来会持续更新使用Swift3.0开发服务端相关的博客.当然,我们使用目前使用Swift开发服务端较为成熟的框架Perfect来实现.Perfect框架是加拿大一个创业团队开发 ...
- .NET跨平台之旅:将示例站点升级至 ASP.NET Core 1.1
微软今天在 Connect(); // 2016 上发布了 .NET Core 1.1 ,ASP.NET Core 1.1 以及 Entity Framework Core 1.1.紧跟这次发布,我们 ...
- 通过Jexus 部署 dotnetcore版本MusicStore 示例程序
ASPNET Music Store application 是一个展示最新的.NET 平台(包括.NET Core/Mono等)上使用MVC 和Entity Framework的示例程序,本文将展示 ...
随机推荐
- andorid jar/库源码解析之Butterknife
目录:andorid jar/库源码解析 Butterknife: 作用: 用于初始化界面控件,控件方法,通过注释进行绑定控件和控件方法 栗子: public class MainActivity e ...
- MODIS系列之NDVI(MOD13Q1)五:NDVI处理流程
前言:(个人建议) 1.进行数据处理工作,由于通常数据量比较大.所以在个人电脑中,要将基础数据.不断增长的过程数据.结果数据等分门别类,使得简单易找. 2.将重要数据备份,因为在数据处理过程中,由于出 ...
- CTF-Pwn-[BJDCTF 2nd]diff
CTF-Pwn-[BJDCTF 2nd]diff 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢!本文仅用于学习与交流,不得用于非 ...
- layui里面的layer模块弹窗,强制居中的方法!!!
每次调用layer弹窗做动态展示的时候,只要内容不固定或者需要二次渲染 比如layui.form.render()进行渲染的时候 由于弹窗已经出来了,只是content部分的结构改变了宽度或者高度,l ...
- 【Spark】一起了解一下大数据必不可少的Spark吧!
目录 Spark概述 官网 Spark是什么? 特点 Spark架构模块 主要架构模块 Spark Core Spark SQL Spark Streaming MLlib GraghX 集群管理器 ...
- 用PHP获取网页上的信息相对于xpath效率低点
用php实现对网页的抓取,及信息的收集,其实就是爬数据,具体实现步骤如下,首先应引入两个文件curl_html_get.php和save_file.php文件,两个文件具体代码是这样的curl_htm ...
- 数组的操作。1,JS数组去重。2,把数组中存在的某个值,全部找出来。3在JS数组指定位置插入元素。。。
1,数组去重 let arr = [1,2,3,4,5,6,1,2,3,'a','b','a']; let temp = []; // 作为存储新数组使用 for(let i = 0; i < ...
- 设计者模式之GOF23命令模式
命令模式Command 将一个请求封装为一个对象,从而使我们可用不同的请求对客户参数化:对请求排队或者记录请求日志,以及支持可撤销的操作.也称之为:动作Action模式,事务transaction模式 ...
- hdu5381 The sum of gcd]莫队算法
题意:http://acm.hdu.edu.cn/showproblem.php?pid=5381 思路:这个题属于没有修改的区间查询问题,可以用莫队算法来做.首先预处理出每个点以它为起点向左和向右连 ...
- js理论-函数中的Arguments对象
详情参考:https://github.com/mqyqingfeng/Blog/issues/14 如果: arguments和实参的关系,以及arguments的属性 附上代码和注解 functi ...