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

相关文章

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

springboot security验证码的登录实例

《springbootsecurity验证码的登录实例》:本文主要介绍springbootsecurity验证码的登录实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录前言代码示例引入依赖定义验证码生成器定义获取验证码及认证接口测试获取验证码登录总结前言在spring

SpringBoot中封装Cors自动配置方式

《SpringBoot中封装Cors自动配置方式》:本文主要介绍SpringBoot中封装Cors自动配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot封装Cors自动配置背景实现步骤1. 创建 GlobalCorsProperties

idea中创建新类时自动添加注释的实现

《idea中创建新类时自动添加注释的实现》在每次使用idea创建一个新类时,过了一段时间发现看不懂这个类是用来干嘛的,为了解决这个问题,我们可以设置在创建一个新类时自动添加注释,帮助我们理解这个类的用... 目录前言:详细操作:步骤一:点击上方的 文件(File),点击&nbmyHIgsp;设置(Setti

tomcat多实例部署的项目实践

《tomcat多实例部署的项目实践》Tomcat多实例是指在一台设备上运行多个Tomcat服务,这些Tomcat相互独立,本文主要介绍了tomcat多实例部署的项目实践,具有一定的参考价值,感兴趣的可... 目录1.创建项目目录,测试文China编程件2js.创建实例的安装目录3.准备实例的配置文件4.编辑实例的

python+opencv处理颜色之将目标颜色转换实例代码

《python+opencv处理颜色之将目标颜色转换实例代码》OpenCV是一个的跨平台计算机视觉库,可以运行在Linux、Windows和MacOS操作系统上,:本文主要介绍python+ope... 目录下面是代码+ 效果 + 解释转HSV: 关于颜色总是要转HSV的掩膜再标注总结 目标:将红色的部分滤

SpringBoot项目启动报错"找不到或无法加载主类"的解决方法

《SpringBoot项目启动报错找不到或无法加载主类的解决方法》在使用IntelliJIDEA开发基于SpringBoot框架的Java程序时,可能会出现找不到或无法加载主类com.example.... 目录一、问题描述二、排查过程三、解决方案一、问题描述在使用 IntelliJ IDEA 开发基于

Spring 中使用反射创建 Bean 实例的几种方式

《Spring中使用反射创建Bean实例的几种方式》文章介绍了在Spring框架中如何使用反射来创建Bean实例,包括使用Class.newInstance()、Constructor.newI... 目录1. 使用 Class.newInstance() (仅限无参构造函数):2. 使用 Construc