关于PHP的自动加载知识整理
1. 先说说上个世纪的引入案例吧
在没有php自动加载的时候很多小项目都采用require 和 include 的方式来加载其他类里面的内容。将很多其他类的内容通过这种方式加载到php的函数根目录下面。实现类的复用。但是也有一部分问题如下:
1、首先是方法名的重复。代码的增多难免会导致方法的重名,比较难处理。
2、软件的维护工作比较繁琐。看的头晕眼花。。。。
3、代码看起来不是特别顺眼,比较别扭。
来个例子吧:
这是一个ceshi类,包含一个构造方法,我们打印一串字符串
这是一个使用require_once来引入该文件的案例,实例该类会打印出
‘--------test_construct--------’
ps:
在这里解释一些require_once 和 include_once的区别吧。首先是这个两个函数相较于原函数只会加载一次,二次加载会自动复用原内容。 其次require可以理解为依赖,如果文件不存在,会导致系统报出致命错误并且停止运行,该函数没有返回值。 而 include 可以理解为包含,如果文件不存在只会报一个警告,不影响继续执行,且该函数有一个false或true的返回值。 require_once和include_once一样继承该特点。
2. 在系统逐步变大的时候来了点新想法
在此之前我们有必要先了解了解系统在new 一个对象的时候做了什么,我们写一个系统的实例过程来演示:
1.首先系统会在已经加载的类库中寻找是否存在,存在则返回对应实例。
2.查看用户是否自定义自动加载函数autoload,由用户自定义实例过程。
3.如果还是没有发现这个类,则报错 Class Not Found
现在我们再说说一些类加载的改进思路。很多人在想,既然每个类都有对应的路径,那为什么我不写一个通用的路径加载办法呢,这个类包含了静态变量存储每个类的类名对应的路径地址,我只需要传入类名,自动调用对应的路径然后返回实例化对象呢。 说做就做,来点例子:
——我们将类和路径地址封装在一个数组当中,当用户传入所需要的类时候,自动调用地址实例后返回该对象。貌似已经解决了这个问题。。。。
来说说缺点吧: 这个可能在小的系统中颓势不太明显,但是在大一点的系统当中可能单单这个类的映射数组就会搞的无限长。这并不是我们想要的结果。
3.来自命名空间的改进
由上面的例子,我们这个时候就在想,如果每个类自带地址,这样就可以不用写那么那么长的数组映射了。 如此的想法,命名空间应运而生了。此时多了个关键字 namespace ,如果我们将namespace 作为我们类的地址那就可以不需要实现那么长的映射了。
在这里我们还是要说一下 命名空间的规范:
和路径类似 存在相对命名空间 和 绝对命名空间。如果类似 /app/test 这种以 / 开头的明明空间通常指的是根命名空间下的地址。如果app/test 则是相对此文件路径下的地址。具体不多赘述。可百度;
我们还是举例子来说吧
我们可以实现一个autoload类来实现
我们定义一个内容目录 app 通过系统函数spl_autoload_register将类的实例工作交给该类的autoload方法,首先我们通过findFile方法找到该文件的路径。再通过includeFile方法 包含该类,实现实例过程;该过程参考thinkphp5
当然我们不能每次写类的时候总是带着全名称。所以系统来了个use 语法糖。 我们可以在namespace 下使用use 将所需要的类 起一个别名
use app/test as testObj;
这样我们就方便多了;
end!