PSR4是一种自动加载规范,老版本是PSR0,尽管thinkPHP支持PSR4和PSR0的自动加载方式,但是默认也是优先进行PSR4加载,如果失败,再进行PSR0的加载。本篇文章只会讨论PSR4的加载。

代码示例:

spl_autoload_register(function ($class) {

    // 指定项目的命名空间前缀
$prefix = 'Foo\\Bar\\'; // 指定项目的根目录
$base_dir = __DIR__ . '/src/'; // 判断类的前缀是不是上面的命名空间前缀
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
// 不是,则交给其他类加载器去加载,不使用PSR4
return;
} // 获取相对的命名空间
$relative_class = substr($class, $len); // replace the namespace prefix with the base directory, replace namespace
// separators with directory separators in the relative class name, append
// with .php
// 使用根目录替换命名空间前缀,使用目录分隔符替换相对类名中的命名空间分隔符,然后再加上.php
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; // 如果该类存在,则require它
if (file_exists($file)) {
require $file;
}
});

从上面的代码中,我们就可以知道PSR4到底是干什么的。
这个规范主要就是将类转换成物理路径。

  1. 命名空间前缀使用根目录替换
  2. 去掉命名空间前缀剩下的部分,叫做它相对类名
  3. 使用目录分隔符替换掉相对类名中的命名空间分隔符(也就是\变成/)
  4. 加上.php

比如thinkphp典型的一个控制器:Index.php

<?php
namespace app\index\controller; class Index{
}

那么在加载的时候,传给这个PSR4的时候,$class=app\index\controller\Index;

假设当前的根目录为:E:\app
当前的命名空间前缀为:app
根据前面的转换步骤,这个类的路径应该是在:
E:/app/index/controller/Index.php

路径的斜杆(/)跟反斜杆(\)。在windows中通常是使用反斜杆作为路径分隔符的,而在linux中,通过是使用斜杆作为路径分隔符的。不过windows现在的API都支持使用斜杆作为路径分隔符了,而如果使用反斜杆的话,那么在单引号中,还需要写成\才能当成\。而linux中是使用/,因此我们的路径表示便是使用斜杆了。

有同学跟我反映说,php单引号不是不会被转义吗?这个确实是,不过对于要输出单引号,因此在单引号字符串中,单引号是需要使用反斜杆转义才能输出的,而反斜杆本身也是需要使用反斜杆来转义,对于其他的转义,就真的不会了。

thinkphp5的类加载

类库映射实际上就是保存一个键值对数组,键值为类名,值为物理路径,这样当类加载的时候,直接查找该数组就行。

而对于PSR4,我们根据上面知道,需要注册根目录跟命名空间前缀。
在thinkphp中注册了五个命名空间前缀:

self::addNamespace([
'think' => LIB_PATH . 'think' . DS,
'behavior' => LIB_PATH . 'behavior' . DS,
'traits' => LIB_PATH . 'traits' . DS,
]);

还有两个是可以配置的:

self::$namespace = $config['app_namespace'];
Loader::addNamespace($config['app_namespace'], APP_PATH);
if (!empty($config['root_namespace'])) {
Loader::addNamespace($config['root_namespace']);
}

因此在配置文件中的app_namespace就是指明应用的命名空间前缀。比如默认为app对应着跟目录为application。

PSR4的备选目录

当使用PSR4方式读取失败的话,那么还有备选的目录可以用来读取,thinkphp便是使用这种方式作为扩展目录的读取:

// 查找 PSR-4 fallback dirs
foreach (self::$fallbackDirsPsr4 as $dir) {
if (is_file($file = $dir . DS . $logicalPathPsr4)) {
return $file;
}
}

$logicalPathPsr4就是这事将命名空间分隔符转换为目录分隔符再加上.php而已。

不过,通常来说,开源的扩展应该使用composer开发。而只有私人的扩展,一般才放在extend目录下的。

为什么TP不完全使用composer的加载器呢?
一是完全基于composer的话,那么当composer更新的时候,框架也需要相对应地调整,因此不能够完全地专注于框架的开发。二如果完全抛弃composer而专注于框架,又像是捡了芝麻丢了西瓜。因此将composer作为框架的延伸扩展,无疑是一种比较好的折中方案。


原文链接:https://www.kancloud.cn/code7/tp5/343057

php自动加载规范 PSR4 (Thinkphp)的更多相关文章

  1. PHP 自动加载规范PSR-4

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...

  2. 【PSR规范专题(5)】PSR-4 改进后的自动加载规范

    本文转自: https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 关键词 "必须"(&quo ...

  3. PHP自动加载下——PSR4

    1.先来介绍一下PSR规范 PHP-FIG,它的网站是:www.php-fig.org.就是这个联盟组织发明和创造了PSR规范,其中自动加载涉及其中两个规范,一个是PSR0,一个是PSR4, PSR0 ...

  4. PSR-4 规范实例讲解 -- php 自动加载

    参考 参考文档:https://www.kancloud.cn/thinkphp/php-fig-psr/3144 参考实例:https://github.com/php-fig/fig-standa ...

  5. 如何实现一个php框架系列文章【3】支持psr4的自动加载类

    psr4自动加载规范https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-4-autoloader-cn.md 我们把第三方使用psr规范的类库放在v ...

  6. PSR-4 自动加载器

    div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,cod ...

  7. 基于PHP规范的自动加载方式(composer配置)

    针对PHP这种编程语言,到目前FIG指定了五个规范,分别如下: PSR0:自动加载: PSR1:基本代码规范: PSR2:代码样式规范: PSR3:日志接口规范: PSR4:自动加载规范: 看上去PS ...

  8. thinkphp5.0 自动加载

    自动加载 概述 ThinkPHP5.0真正实现了按需加载,所有类库采用自动加载机制,并且支持类库映射和composer类库的自动加载. 自动加载的实现由think\Loader类库完成,自动加载规范符 ...

  9. thinkphp5.0自动加载

    概述 ThinkPHP5.0 真正实现了按需加载,所有类库采用自动加载机制,并且支持类库映射和composer类库的自动加载. 自动加载的实现由think\Loader类库完成,自动加载规范符合PHP ...

随机推荐

  1. FPGA学习笔记(二)——FPGA学习路线及开发流程

    ###### [该随笔部分内容转载自小梅哥]       ######### 一.FPGA学习路线 工具使用 -> 语法学习 -> 逻辑设计 -> IP使用 ->接口设计 -& ...

  2. localStorage和sessionStorage区别(包括同源的定义)

    localStorage和sessionStorage一样都是用来存储客户端临时信息的对象. 他们均只能存储字符串类型的对象(虽然规范中可以存储其他原生类型的对象,但是目前为止没有浏览器对其进行实现) ...

  3. 查找linux设备的uuid

    [root@ ~]# blkid /dev/vdc /dev/vdc: UUID="bxxxx-xxx-41b9-8146-7da8bd645b92" TYPE="ext ...

  4. Golang Multipart File Upload Example

    http://matt.aimonetti.net/posts/2013/07/01/golang-multipart-file-upload-example/ The Go language is ...

  5. 解决python2.x用urllib2证书验证错误, _create_unverified_context

    解决以下错误: 错误1:AttributeError: 'module' object has no attribute '_create_unverified_context', 错误2:URLEr ...

  6. MySQL 开发实践 8 问,你能 hold 住几个?

    最近研发的项目对DB依赖比较重,梳理了这段时间使用MySQL遇到的8个比较具有代表性的问题,答案也比较偏自己的开发实践,没有DBA专业和深入,有出入的请使劲拍砖!- MySQL读写性能是多少,有哪些性 ...

  7. 网络流解线性规划问题 BZOJ1061: [Noi2008]志愿者招募

    线性规划定义: 在给定有限的资源和竞争约束情况下,很多问题都可以表述为最大化或最小化某个目标.如果可以把目标指定为某些变量的线性函数,而且如果可以将资源约束指定为这些变量的等式或不等式,则得到了一个线 ...

  8. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  9. javascript && php &&java 轰炸!!!

    java && javascript && php 轰炸!!!恢复 1.javascript简介 *是基于对象和时间的驱动语言,应用于客户端. -----基于对象: * ...

  10. 对图片进行索引,存入数据库sqlite3中,实现快速搜索打开

    对图片进行索引,存入数据库中,实现快速搜索打开    这个任务分为两步: 第一步:建立索引 import os import shutil import sqlite3 # 扫描函数,需扫描路径目录处 ...