一个遵循PSR-4的文件autoload的例子

一、简介

  首先这里要了解PSR,Proposing a Standards Recommendation(提出标准建议)的缩写,就是一种PHP开发规范,让我们研发出来的代码更合理、更好维护、可读性更高。PSR有下面几个标准:

  •   PSR-0:自动加载
  •   PSR-1:基本代码规范
  • PSR-2:代码样式
  •   PSR-3:日志接口
  •   PSR-4:规范自动加载的路径问题

  这里看出PSR的下标也是从0开始的,和数组还有点像~。其实PSR-4和PSR-0是有点相似甚至冗余的,他们都说明的是自动加载的规范,只不过PSR-4中的规范更加简洁,在PSR-0中下划线"_"是有特殊含义的,在autoload处理的时候需要将下划线转换为目录分隔符,而在PSR-4中下划线是没有任何特殊含义的,所以在文件自动加载的时候显得更加简洁、调理更加清楚。

  我对github上面的psr-4规范中的例子进行了大概的翻译(相信你们的英语水平一定比我好,肯定可以看懂^_^),然后以这个自动加载类库做了一个小小的例子,例子文件多、长,放在这里不太合适,所以我在博客中就大概介绍下这个例子,想要详细了解的可以去我的github主页去看这个例子。

二、 自动加载类库介绍

  首先看下自动加载类的大概内容:

class Autoload

  {
    // 注册自动加载函数到spl autoload栈中.
     public function register();

    // 添加一个目录到一个命名空间前缀中
    public function addNamespace($prefix, $base_dir, $prepend=false);

    // 自动加载函数,会在$this->register中用到
    public function loadClass($class);

    // 寻找映射的文件
    public function loadMappedFile($prefix, $relative_class);

    //查看一个文件是否在文件系统中存在
    public function requireFile($file);

  }

  自动加载类库函数中就这几个函数,其中register()、addNamespace()、loadMappedFile()、requireFile()函数都比较简单,一看就懂,唯一一个可能需要解释下的函数就是loadClass函数,先看下loadClass()函数的代码:

 1     public function loadClass($class)
 2     {
 3         // 当前的命名空间前缀
 4         $prefix = $class;
 5
 6         //通过命名空间去查找对应的文件
 7         while (false !== $pos = strrpos($prefix, ‘\\‘)) {
 8
 9             // 可能存在的命名空间前缀
10             $prefix = substr($class, 0, $pos + 1);
11
12             // 剩余部分是可能存在的类
13             $relative_class = substr($class, $pos + 1);
14
15             //试图加载prefix前缀和relitive class对应的文件
16             $mapped_file = $this->loadMappedFile($prefix, $relative_class);
17             if ($mapped_file) {
18                 return $mapped_file;
19             }
20
21             // 移动命名空间和relative class分割位置到下一个位置
22             $prefix = rtrim($prefix, ‘\\‘);
23         }
24
25         // 未找到试图加载的文件
26         return false;
27     }

  其实有疑惑的地方可能也只有一个,那就是为什么这里要循环着去试图查找文件,在while循环中,会慢慢的缩短命名空间前缀的名称去需找合适的命名空间前缀,为什么要这么做呢?

  循环查找文件是为了在命名空间中包含更多的内容,不用每次在父命名空间中新建一个文件夹的时候都去添加一个新的命名空间前缀,就像下面这个图中描述的那样:

  当一个文件在一个命名空间下的子目录下的时候,我们不用去新建命名空间前缀就可以成功加载需要的文件,维护命名空间前缀的数组内容更少,更好维护。相反的如果没有循环查找,就是下面这个样子的

  

  每次新建一个子目录就要去新加一个命名空间前缀,是不是很麻烦,但这样的话也有一定的好处,就是加载的时候不晕循环查找文件,可能会减小一定的时间消耗,但就是加载的时候有点麻烦。

  所以,用循环加载这种方式还是比较方便的,但是一定不能让没有命名空间前缀的目录层级太深,这样会消耗不必要的时间到文件加载上。当需要效率很高的时候,而我们的目录肯定又不会不确定,这个时候加载的时候去掉循环查找,而是为每个目录添加命名空间,效率可能会提高,只是我的一点愚见。

三、 例子

  说道这里你可能已经对自动加载的内容比较了解了,这个时候趁热打铁看看我准备的小例子,这里只是介绍下小例子的目录结构,由于比较简单,详细的内容就不再这里列了,感兴趣的通许可以去我的github主页看看这个例子

  --core

    -Autoload.php

  --vendor

    --test1

      -hello.php

    --test2

      -world.php

  -App.php

  本文版权归作者([email protected])和博客园共有,未经作者本人同意禁止任何形式的转载,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

时间: 2024-10-09 07:55:12

一个遵循PSR-4的文件autoload的例子的相关文章

删除一个目录下的所有文件,但保留一个指定文件

此题问题虽小,但是初学者还是很难给出合理的答案的!本文来自老男孩21期网络班学员 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 面试题:删除一个目录下的所有文件,但保留一个指定文件 解答: 假设这个目录是/xx/,里面有file1,file2,file3..file10  十个文件

创建一个程序读入和显示视频文件,并可以使用滑动条控制视频文件的播放。一个滑动条用来控制视频播放位置,以10为步长跳进。另一个滑动条用来控制停止/播放

/* 创建一个程序读入和显示视频文件,并可以使用滑动条控制视频文件的播放. 一个滑动条用来控制视频播放位置,以10为步长跳进.另一个滑动条用来控制 停止/播放 */ #include <cv.h> #include <highgui.h> int g_slider_position = 0; CvCapture* g_capture = NULL; int index = 0; bool flag = true; int g_slider_position1 = 0; void o

JAVA之File类 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件

package ioTest.io3; import java.io.File; /* * 获取一个目录下的所有文件夹和文件,包括子文件夹和子文件 . * 并将文件夹和文件名称打印在控制台上面.并且要显示文件目录的层级 * 注:运用了递归的算法. */ public class FileDemo3 { public static void main(String[] args) { File dir=new File("F:\\黑马学习日程\\"); //File dir=new Fi

获取一个想要的指定文件的集合,获取文件夹下(包含子目录的所有.java的文件对象,并存储到集合中)

import java.io.File; import java.io.FileFilter; import java.io.ObjectInputStream.GetField; import java.util.ArrayList; import java.util.List; public class huoquwenjian { /*获取一个想要的指定文件的集合,获取文件夹下(包含子目录的所有.java的文件对象,并存储到集合中) * 思路: * 1,既然包含子目录,就需要递归. * 2

eclipse中如何查看一个android模拟器的内部文件

eclipse中如何查看一个android模拟器的内部文件,有时要在其中添加一个文件夹或是什么的,要手动的做这件事,而不能够用代码去完成时,就要用这个方法了. 1.首先,打开一个安卓模拟器. 2.这个时候,点击eclipse中DDMS图标,打开android模拟器的控件台. 3.在这里,你就能够看到这个模拟器了,同时它的一些状态,你也是可以看到的. 4.下面就点击右侧file explore就可以看到其中的文件系统了,在这里面,你就可以看到你要的文件了.

jfinal初接触,一个简单的文件上传例子

写了个上传的小例子. 从jfinal官网下载jfinal-1.8_demo_for_jsp.zip 然后下载jfinal-1.8-lib.zip 按要求删掉该删除的,引入一些包,之后的项目结构: DemoConfig.java中配置路由,只留下了根路径: /** * 配置路由 */ public void configRoute(Routes me) { me.add("/", CommonController.class); //me.add("/blog", B

iis提示“另一个程序正在使用此文件,进程无法访问。(异常来自HRESULT:0x80070020)

看看IIS的网站,惊人的发现default web site是停止状态.印象中没有停止它啊.右键->管理网站->启动.点击启动后居然弹出:"另一个程序正在使用此文件,进程无法访问.(异常来自HRESULT:0x80070020)"也就是我的default web site 无法启动. 上次一顿搜索,欣喜的发现好文章一篇(http://www.cnblogs.com/rickie/articles/49016.html),描述的情况和我的情况基本一样,参考下, 运行 cmd

统计一个目录下所有普通文件的总行数

1. 统计一个目录下所有普通文件的总行数 #实用场景:毕业设计时,需要统计自己的代码行数# 方案一:find . -type f -name "*.c" -exec cat {} \; | grep -v '^$' | wc -l 解释:find . -type f -name "*.c" 查找当前目录下所有以.c结尾的文件,如果不考虑文件类型,可以直接实用find . -type f即可. -exec cat {} \; 是将找到的文件采用cat命令输出; gre

记一个使用Client Object Model上传文件的小例子

1. 新建一个C#的Console project. 2. 给project 添加reference: Microsoft.SharePoint.Client Microsoft.SharePoint.Runtime 3. 修改project的属性: Platform target – x64 Target framework – .NET Framework 4 4. 修改代码如下: using System; using System.IO; using System.Net; using