开发者学堂课程【PHP 进阶教程-由浅入深掌握面向对象开发-第一阶段:类的加载(autoload 自动加载)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/711/detail/12671
类的加载(autoload 自动加载)
主要内容
一、自动加载示例
一、自动加载示例
自动加载:PHP 没有那么智能的系统自动加载,所谓自动加载只是 PHP 提供了一种加载机制:即实现定义一个函数__autoload(), 然后当系统需要使用类,而内存中又不存在的时候,系统就会自动调用__autoload()函数来加载类文件。
#自动加载机制:利用系统提供的__autoload()函数
function __autoload($classname){ #参数为类名:即当前需要访问的类的名字
#需要人为定义去哪加载,怎么加载
include_ once $classname .'.php'; #假定为当前目录下,类文件名字为:类名.php
}
#使用类:内存目前并没有
$s = new saler();#系统发现内存没有 Saler,所以调用__autoload()去加载
<?php
#__autoload实现自动加载
#使用类
$b = new Buyer();
报错,因为没有这个类。使用自动加载解决这个问题。
#自动加载
function__autoload(){
}
报错,这个函数必须有一个参数,按照要求来,给个参数$a,
#自动加载
function__autoload($a){
}
这个东西已经过期了,不建议使用,先放着,因为这不致命,但问题是它没有加载到类 Buyer。所以要在里面实现类的加载,
#实现类的加载
include ' Buyer.php';
可以了。
此时如果还想$s new Saler(),这段代码又不能用了,
不是类没有,而是没有找到,因为写 include Buyer.php,而且不能重定义 Buyer,因为已经存在了,所以这时要看$a,
echo $a;
原来在前面 Buyer 类实例化的时候叫 Buyer,Salar 类实例化的时候叫 salar,这个代表类名,类名确定文件关联关系,所以此时就要知道怎么合理运用它,有参数的要求。
#echo $a; #形参代表类名
#实现类的加载
#include ' Buyer.php' ;
#动态加载
include $a .php ';
抛开这个问题,两个都成功了,所以它就实现了自动加载。有1000个可以用它,有1万个也可以用它,所以自动加载带来的是效率问题。
用 once 可以保证它的安全,但是正常还是应该这么写,合理的逻辑,
$file = $a.'php' ;
if( !class_ exists($file))
include $a‘.php';
不存在就加载,存在就没关系,实现一下,
效果是一样的,只是$s2 = new Saler();不会报错,
这是安全性的一个处理。
4、一个系统里,可能类文件会放到不同的路径下,有很多的路径,有很多的文件,因为要把类进行分类、再分类,看到底属于什么样的业务范畴,因此一个完整的自动加载函数,应该要进行文件判定以及加载功能
#定义自动加载
function__autoload($classname){
#组织文件路径:假设当前路径下,有两个文件夹下都有类 c 和 m
$c_ file = 'c/'.$classname .' . php' ; #如 c/saler. php
if(!file_ exists($c_ file)){
include_ once $c_ file;
return true;
}
#说明 c 文件夹没有对应的文件
$m file = 'm/' .$classname .' . php' ; #如 m/Saler . php
if(!file_ exists($m_ file)){
include_ once Sm_ file;
return true;
}
}
传的依然只是一个类名,但是有可能这个文件在 c 目录下面,比如当前目录下面的 c/saler. php,还有可能在 m 目录下面,先判定 C 文件是否存在,存在的话,发 exists,自然是什么都不做的,如果是不存在这个文件,加载一下,然后返回一个 true,不返回也行,因为基本上不会出现同名文件,有了 return true 能够让效率更高,下面代码自动终止。同样,如果还有其他的,就判定其他的目录,如果有十个目录,就写十个这样的代码去判定它,保证能加载到,这样哪个文件夹里面都可以自动加载,所以整个项目都可以实现自动加载,这就是自动加载机制。
注意:自动加载并不是真正的能够自动的加载代码,而是它有自动触发的机制,要去寻找对应的文件实现包含,必须要自己把它写好,而且如果写好的代码因为人为的犯错,发现这个类不存在或者类名出现错误,那么这时它报的错它也不负责处理,因为这是开发者自己犯的错,系统不能规避。定义了一个 s 类,非要访问一个 a 类,这就是跟系统过不去,所以这种方法要用一定是自己去处理好内部的逻辑,保证能够加载到,同时不出错,这就是实现自动加载最基本的事情。
以上的方式,是使用__autoload(),也就是默认提供的系统函数魔术函数来实现的,但是这种方式系统已经不建议使用了,因为现在的版本是在 PHP 以上,所以他不建议使用,应该用 spl__autoload register() instead 替换。