为什么用类的自动加载?
- 在系统开发过程中,不可能把所有的类都写在一个PHP文件中,当一个PHP文件中需要调用另一个文件中声明的类时,就需要通过include或require把这个文件引入。
- 在类文件众多的项目中,要将所需类的文件都逐个引入,是一个很麻烦的工作。那么我们能不能在用到什么类的时候,再把这个类所在的PHP文件引入呢?
实现类的自动加载的方法
法一:__autoload()魔术方法实现
- 在PHP5中,可以定义一个__autoload()函数,它会在试图使用尚未被定义的类时自动调用,通过调用此函数,脚本引擎在PHP出错失败前有了最后一个加载所需的类。
- __autoload($className)函数接受的一个参数,就是你想加载的类的类名,所以你做项目时,在组织定义类的文件名时,需要按照一定的规则,最好以类名为中心,也可以加上统一的前缀或后缀形成文件名。
- set_include_path(),是在脚本里动态地对PHP.ini中的include_path进行修改的。动态设置包含目录(预定义include和require的路径范围)
- 加载lib目录下的类
//set_include_path()设置include默认查询所有类的目录
//get_include_path():获取当前路径;PATH_SEPARATOR:路径分割符;"lib/":拼接lib路径
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/");
当前位置新建lib文件,并其内部建立Test.php和Test1.php,内部再设置下面new到的类
//设置include默认查询所有类的目录
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/");
function __autoload($className)
{
include $className.'.php';
}
new Test();//我是lib文件下的Test.php中的Text类
new Test1();//我是lib文件下的Test1.php中的Text1类
法二:spl_autoload_register()
- 此函数的功能就是把函数注册至SPL的__autoload函数栈中,并移除系统默认的__autoload()。
function __autoload($class_name)//失效
{
echo '__autoload class:' . $class_name . '<br>';
}
function classLoader($class_name)
{
echo 'SPL load class:' . $class_name . '<br>';
}
//把函数注册至SPL的__autoload函数栈中,并移除系统默认的__autoload()
spl_autoload_register('classLoader');
//下面的显示说明屏蔽了__autoload()
new Test();//SPL load class:Test
- spl_autoload_register()可以调用多次。它实际上创建了autoload函数的队列,按照定义时的顺序逐个执行。而__autoload()只可以定义一次。
当前位置新建lib文件,并其内部建立Test.php和Test1.php,内部再设置下面new到的类
//设置include默认查询所有类的目录
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/");
function classLoader($className)
{
echo 'classLoader '.$className.'<br>';
include $className.'.php';
}
function addClassLoader($className){
echo 'addClassLoader '.$className.'<br>';
}
//注册两个
spl_autoload_register('classLoader');
spl_autoload_register('addClassLoader');
new Test();//classLoader Test 我是lib文件下的Test.php中的Text类
new Test1();//classLoader Test1 我是lib文件下的Test1.php中的Text1类
//一个类先从第一个注册中找,若找不到,再从第二个注册中找,以此类推
new t();//classLoader t addClassLoader t
- 如果注册的自动加载函数是一个类的方法,则参数可以传递为一个数组;格式为spl_autoload_register(array(类名,方法名));
//设置include默认查询所有类的目录
set_include_path(get_include_path() . PATH_SEPARATOR . "lib/");
class AutoLoad{
public static function loadClass($className){
echo 'AutoLoad 中的 loadClass '.$className.'<br>';
include $className.'.php';
}
}
spl_autoload_register(array('AutoLoad','loadClass'));
new Test();//AutoLoad 中的 loadClass Test 我是lib文件下的Test.php中的Text类
new Test1();//AutoLoad 中的 loadClass Test1 我是lib文件下的Test1.php中的Text1类