官方解释
bool spl_autoload_register ([ callable $autoload_function [, bool $throw = true [, bool $prepend = false ]]] )
将函数注册到SPL __autoload函数队列中。如果该队列中的函数尚未激活,则激活它们。
如果在你的程序中已经实现了__autoload()函数,它必须显式注册到__autoload()队列中。因为 spl_autoload_register()函数会将Zend Engine中的__autoload()函数取代为spl_autoload()或spl_autoload_call()。
如果需要多条 autoload 函数,spl_autoload_register() 满足了此类需求。 它实际上创建了 autoload 函数的队列,按定义时的顺序逐个执行。相比之下, __autoload() 只可以定义一次。
没有看懂官方说的是什么,我也只是PHP的初学者,下面是我做的测试。
代码如下
class framework{
public function runApp(){
$this->loadConfig(); //加载配置
$this->registerAutoLoad(); //注册自动加载方法
$this->getRequestParams(); //获得请求参数
$this->dispatch(); //请求分发
}
/**
* 注册自动加载方法
*/
private function registerAutoLoad(){
spl_autoload_register(array($this,'user_autoload'));
}
/**
* 自动加载方法
* $param $class_name string 类名
*/
public function user_autoload($class_name){
echo $class_name."<br>";
//定义基础类列表
$base_classes = array(
//类名 => 所在位置
'model' => './framework/model.class.php',
'MySQLPDO' => './framework/MySQLPDO.class.php',
'page' => './framework/page.class.php',
);
//依次判断 基础类、模型类、控制器类
if (isset($base_classes[$class_name])){
require $base_classes[$class_name];
}elseif (substr($class_name,-5) == 'Model'){
require './application/'.PLATFORM."/model/{$class_name}.class.php";
}elseif (substr($class_name, -10) == 'Controller'){
require './application/'.PLATFORM."/controller/{$class_name}.class.php";
}
}
/**
* 载入配置文件
*/
private function loadConfig(){
//使用全局变量保存配置
$GLOBALS['config'] = require './application/config/app.conf.php';
}
/**
* 获取请求参数,p=平台 c=控制器 a=方法
*/
private function getRequestParams(){
//当前平台
define('PLATFORM', isset($_GET['p']) ? $_GET['p'] : $GLOBALS['config']['app']['default_platform']);
//得到当前控制器名
define('CONTROLLER', isset($_GET['c']) ? $_GET['c'] : $GLOBALS['config'][PLATFORM]['default_controller']);
//当前方法名
define('ACTION', isset($_GET['a']) ? $_GET['a'] : $GLOBALS['config'][PLATFORM]['default_action']);
}
/**
* 请求分发
*/
private function dispatch(){
//实例化控制器
$controller_name = CONTROLLER.'Controller';
$controller = new $controller_name;
echo $controller_name;
}
}
暂且不管这个类的作用,我们实例化这个类,并执行runApp()函数,来研究下spl_autoload_register函数是怎么用的。
执行runApp函数,无一例外的顺序执行
$this->loadConfig(); //加载配置
$this->registerAutoLoad(); //注册自动加载方法
$this->getRequestParams(); //获得请求参数
$this->dispatch(); //请求分发
……中间测试过程略。
结果
无论spl_autoload_register函数运行顺序如何,只有当实例化一个类的时候才会触发函数,并且如果实例化的类有父类,也会把父类加载过来(循环触发)。如有理解错误,请指教!