为什么要实现自动加载机制?
在大项目中,就不用每次include/require文件,省心又高效,只要你不嫌累的话,就可以不使用。
一、spl_autoload_register
语法:
sql_autoload_register(callback $function_name)
__autoload(callback $function_name)
为什么不使用__autoload?而使用spl_autoload_register?
- __autoload因为是一个全局函数,所以只能定义一次,使用多个会冲突报错;而 sql_autoload_register可定义多个,它有效地创建一个队列的自动装载函数并按顺序依次定义。
- spl_autoload_register是触发异常,可被catch捕捉到,而__autoload不可以。
- SPL函数很丰富,有更多的操作空间:如spl_autoload_unregister()注销已经注。册的函数、spl_autoload_functions()返回所有已经注册的函数等
二、代码实现
<?php
/*
test.php
*/
error_reporting(0); // 抑制脚本错误
define('DS',DIRECTORY_SEPARATOR); // 定义目录分隔符常量
use test1\Test1;
use test2\Test2;
Class Test
{
public function __construct()
{
echo __CLASS__.PHP_EOL;
new Test1();
new Test2();
new Test3();
}
}
// 自定义加载器
function autoload($name){
$file = $name.'.php';
if (is_file($name.'.php')){
require_once $file;
}
else{
print_r('已经注册的加载器: ');
print_r(spl_autoload_functions());
print_r($name.'不存在');die;
}
}
// $class_name = __namespace__/__class__
try{
spl_autoload_register('autoload', true);
// spl_autoload_register('autoload1', true); //触发异常
spl_autoload_register('autoload1', false); //无触发异常
}catch (Exception $e){
print_r($e->getMessage());
}
new Test();
/* result:
Test
test1\Test1
test2\Test2
已经注册的加载器: Array
(
[0] => autoload
)
Test3不存在
*/
// 由此可以看出,目录名==空间名(采用小写),文件名==类名(采用大驼峰法),类方法名(采用小驼峰法),函数名(采用下划线)
<?php
/*
test1/Test1.php
*/
namespace test1;
class Test1
{
public function __construct()
{
echo __CLASS__.PHP_EOL;
}
}
<?php
/*
test2/Test2.php
*/
namespace test2;
class Test2
{
public function __construct()
{
echo __CLASS__.PHP_EOL;
}
}
可以推出自动加载的习惯:
- 目录名==空间名(采用小写)。
- 文件名==类名(采用大驼峰法)。
- 类方法名(采用小驼峰法)。
- 函数名(采用下划线)。