废话不多说直接上描述
php的类的自动加载,会连续的多层次的加载文件。这个现象文字不好表达就上实例说话吧。
先看目录结构
1.php作为主文件。a.class.php 和b.class.php为纯类文件
- 1.php的代码如下*
<?php
//注册自动加载函数
spl_autoload_register(function($className){
//构建需要加载文件的路径
$dir="./".$className.".class.php";
//判断文件是否存在,存在则加载
if(file_exists($dir)) require_once($dir);
});
class abc{
public function aaa(){
$bc=new a();//创建类a的实例 类a在a.class.php中。
}
}
echo "在1.php文件中输出<br>";
$t=new abc(); //创建abc的实例
$t->aaa(); //调用aaa成员方法
a.class.php 纯类文件代码如下 注意这里只有类,没有多余的代码 纯类文件无法直接运行
<?php
class a{
public function __construct(){
echo "此语句在a.php文件";
echo "<br>";
$b1= new b(); //在类a的构造方法中创建 类b的实例,类b在b.class.php中
}
}
b.class.php 纯类文件代码如下 注意这里只有类,没有多余的代码 纯类文件无法直接运行
<?php
class b{
public function __construct(){
echo "此语句在b.php文件中";
}
}
运行1.php得到如下输出
出现了一个有意思的现象,我在1.php文件创建 class a的实例时,php的自动加载函数会将a.class.php加载,而在a.class.php的构造方法中游创建了class b的实例,这时php的自动加载函数又会将b.class.php加载。注意自动加载函数只在1.php文件中这种现象我没查到相关的描述,我称之为连续的多层次加载。
注意自动加载函数需要在对象创建之前注册,不然会找不到类,自然也无法创建类的实例 还是看下面的例子吧
首先我们改造一下1.php的代码。其余两个类文件照旧
改造后的1.php的源码如下
<?php
class abc{
//注意这里把自动加载函数封装在class abc 的autoLoad静态方法中
public static function autoLoad(){
spl_autoload_register(function($className){
//构建需要加载文件的路径
$dir="./".$className.".class.php";
//判断文件是否存在,存在则加载
if(file_exists($dir)) require_once($dir);
});
}
public function aaa(){
$bc=new a();//创建类a的实例 类a在a.class.php中。
}
}
echo "在1.php文件中输出<br>";
$t=new abc(); //创建abc的实例
$t->aaa(); //调用aaa成员方法
报错,意思是找不到class a ,连class a都找不到怎么创建它的实例昵??
注意在上面的代码中我创建class abc的实例后 直接调用 aaa成员方法,而成员方法中创建了class a的实例,我明明在class abc中创建了自动加载函数为什么不会自动加载呢?我在上面中提过自动加载函数需要在对象创建之前注册,上图报错就是因为没有注册自动加载函数所造成的。因此我们在更改后的1.php中增加一行代码即可(在倒数第二行增加一行代码,如下所示)
<?php
class abc{
//注意这里把自动加载函数封装在class abc 的autoLoad静态方法中
public static function autoLoad(){
spl_autoload_register(function($className){
//构建需要加载文件的路径
$dir="./".$className.".class.php";
//判断文件是否存在,存在则加载
if(file_exists($dir)) require_once($dir);
});
}
public function aaa(){
$bc=new a();//创建类a的实例 类a在a.class.php中。
}
}
echo "在1.php文件中输出<br>";
$t=new abc(); //创建abc的实例
abc::autoLoad();//调用 autoLoad静态方法进行注册 注意这里是在调用成员方法aaa创建 calss a对象之前。
$t->aaa(); //调用aaa成员方法
注意上面代码的倒数第二行,增加了abc::autoload(),这一行代码。这行代码的作用是调用autoLoad静态方法进行自动加载函数的注册(注意是在类的实例化之前进行注册),再次运行1.php 文件。结果完美运行 如下图
总结
- 如果使用自动加载函数来加载相应的类文件,请在实例化类的对象之前注册自动加载函数。
- 如果使用自动加载的函数加载的类文件中又创建了其它类文件中的实例,那么自动加载函数会自动继续寻找相应的类文件。
最后声明:本人第一次写“技术”博客,因此很多地方有不妥之处敬请原谅。有问题欢迎提出。