刚学PHP那会非常困惑,为什么使用框架时候不需要去require一个文件就能直接声名类了呢?
看了文档后才知道,原来PHP有个__autoload方法.
先说明__autoload方法的作用
<?php new Test1();
执行以上代码,毫无疑问,肯定是报错的
<?php function __autoload($class) { echo "尝试去加载没有定义的 $class 类"; } new Test1();
再执行以上代码,输出如下:
尝试去加载没有定义的 Test1 类
可以看到,如果php脚本中声明了__autoload函数,那么声明一个未定义的类将不会报错,而是去执行了__autoload函数
其中,声明的类名将会自动作为参数传递给__autoload函数.
因此利用这个特性,就可以在函数中加载文件了.
把Test1类放在index.php(执行的文件)同级目录下.
<?php //index.php function __autoload($class) { $EXT ='.php'; require_once("$class".$EXT); } new Test1();
<?php //Test1.php class Test1 { public function __construct() { echo "This is Test1->test1"; } }
输出结果:
This is Test1->test1
这就是最简单的自动加载机制.
但是__autoload有个最大的缺点,一个文件只能有一个__autoload函数,如果你的项目中引用了第三方包,而第三方包也是使用的autoload加载机制,那么就会发生冲突.
因此现在通常使用的方法是 spl_autoload_register()
通过该函数,可以注册多个自动加载的函数,更加灵活,如以下的目录结构
<?php define('EXT','.php'); function load_dir1($class) { $prefix = 'dir1/'; $file = $prefix.$class.EXT; echo "加载".$file.'<br>'; if(is_file($file)){ require_once($file); } } function load_dir2($class) { $prefix = 'dir2/'; $file = $prefix.$class.EXT; echo "加载".$file.'<br>'; if(is_file($file)){ require_once($file); } } spl_autoload_register('load_dir1',false); spl_autoload_register('load_dir2',false); new Test2();
如果spl_autoload_register函数没有第三个参数,那么注册函数是按顺序加入队列尾的.
执行以上代码输出:
加载dir1/Test2.php
加载dir2/Test2.php
This is Test2->test2
可以看到首先执行 load_dir1函数,找不到Test2.php会再次去执行load_dir2函数,直到寻找到为止