php psr 4 实例,PSR-4 自动加载 - 案例

2023-10-24 12:50
文章标签 加载 php 实例 自动 案例 psr

本文主要是介绍php psr 4 实例,PSR-4 自动加载 - 案例,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

da24c7de1d6d

Psr-4-example.jpg

PSR-4 的实现示例

下面的实例描述了符合 PSR-4 的代码:

闭包实例(Closure Example)

/**

* 一个特定项目的实现的实例。

*

*

*/

spl_autoload_register(function ($class) {

$prefix = 'Foo\\Bar\\';

$base_dir = __DIR__ . '/src/';

$len = strlen($prefix);

if (strncmp($prefix, $class, $len) !== 0) {

return;

}

//strncmp() 二进制安全比较字符串开头的若干个字符,第三个参数 $len 指定两字符串比较时使用的长度。

// 即最大比较长度。

$relative_class = substr($class, $len);

// substr() 返回字符串的子串

$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';

// str_replace($search, $replace, $subject) 子字符串替换

if (file_exists($file)) {

require $file;

}

});

类示例(Class 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\ 命名空间前缀的类文件中

如下所示:

// 实例化加载器

$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 类

new \Foo\Bar\Qux\Quux;

下述语句会让自动加载器尝试从

/path/to/packages/foo-bar/tests/Qux/QuuxTest.php

中加载 \Foo\Bar\Qux\QuuxTest 类:

new \Foo\Bar\Qux\QuuxTest;

*/

namespace Example;

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;

}

}

这篇关于php psr 4 实例,PSR-4 自动加载 - 案例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/275278

相关文章

PHP轻松处理千万行数据的方法详解

《PHP轻松处理千万行数据的方法详解》说到处理大数据集,PHP通常不是第一个想到的语言,但如果你曾经需要处理数百万行数据而不让服务器崩溃或内存耗尽,你就会知道PHP用对了工具有多强大,下面小编就... 目录问题的本质php 中的数据流处理:为什么必不可少生成器:内存高效的迭代方式流量控制:避免系统过载一次性

MyBatis分页查询实战案例完整流程

《MyBatis分页查询实战案例完整流程》MyBatis是一个强大的Java持久层框架,支持自定义SQL和高级映射,本案例以员工工资信息管理为例,详细讲解如何在IDEA中使用MyBatis结合Page... 目录1. MyBATis框架简介2. 分页查询原理与应用场景2.1 分页查询的基本原理2.1.1 分

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

PHP应用中处理限流和API节流的最佳实践

《PHP应用中处理限流和API节流的最佳实践》限流和API节流对于确保Web应用程序的可靠性、安全性和可扩展性至关重要,本文将详细介绍PHP应用中处理限流和API节流的最佳实践,下面就来和小编一起学习... 目录限流的重要性在 php 中实施限流的最佳实践使用集中式存储进行状态管理(如 Redis)采用滑动

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

Java 正则表达式的使用实战案例

《Java正则表达式的使用实战案例》本文详细介绍了Java正则表达式的使用方法,涵盖语法细节、核心类方法、高级特性及实战案例,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录一、正则表达式语法详解1. 基础字符匹配2. 字符类([]定义)3. 量词(控制匹配次数)4. 边

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

基于Redis自动过期的流处理暂停机制

《基于Redis自动过期的流处理暂停机制》基于Redis自动过期的流处理暂停机制是一种高效、可靠且易于实现的解决方案,防止延时过大的数据影响实时处理自动恢复处理,以避免积压的数据影响实时性,下面就来详... 目录核心思路代码实现1. 初始化Redis连接和键前缀2. 接收数据时检查暂停状态3. 检测到延时过