您的位置:首页 > 编程语言 > PHP开发

深入理解 spl_autoload , __autoload 以及 spl_autoload_register

2016-08-01 16:50 316 查看
这篇文章将从初学者到进阶同学的角度,循序渐进的谈论一下 PHP 中的自动加载类,以及深入理解 spl_autoload , __autoload ,spl_autoload_register。

什么是加载

学过java 或者c的同学都知道,要在一个文件中使用另一个文件所定义的类,java是通过
import
实现的,而c是通过include 头文件实现的,相对来说都简单,同样,在PHP中也有类似这样的机制,你也可以在前面使用
include
或者
include_once
等等的手段来加载其他类的文件。

除此以外,PHP还有一个自动加载类机制,如果说PHP找不到类的定义(比如说你在A.class.php 中想要new 一个B 类),就会触发自动加载类。

自动加载类之 __autoload

直接上例子

本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类。

<?php
spl_autoload_register(function ($class_name) {
include $class_name . '.php';
});

$obj  = new MyClass1();
$obj2 = new MyClass2();
?>


直接拿来用

在实际开发中,如果我们要使用自动加载类,通常代码是这样

<?php
//Define autoloader
function __autoload($className) {
if (file_exists($className . '.php')) {
require_once $className . '.php';
return true;
}
return false;
}

function canClassBeAutloaded($className) {
return class_exists($className);
}
?>


面试题:如果非要说上面的代码有地方可以改进,你说说是哪里?

没有必要使用require_once 或者是 include_once,因为只有在类找不到的时候才会出发自动加载类。

再进一步

在英文的api中我们发现有这样一句话,

Whilst the __autoload() function can also be used for autoloading classes and interfaces, its preferred to use the spl_autoload_register() function. This is because it is a more flexible alternative (enabling for any number of autoloaders to be specified in the application, such as in third party libraries). For this reason, using __autoload() is discouraged and it may be deprecated in the future.

官方文档中更建议使用
spl_autoload_register
,因为更加灵活,可以保证任意数量的自动加载类在项目中顺利运行,尤其是在使用第三方库。

这个说的并不是很明确,我再解释一下。

谈谈spl_autoload_register()

spl_autoload_register()


允许你注册多个方法,或者静态方法,PHP引擎会把他们放到栈/队列中,当你“new” 一个类的时候,会顺序的调用。

举个例子

spl_autoload_register('myAutoloader');

function myAutoloader($className)
{
$path = '/path/to/class';

include $path.$className.'.php';
}

//-------------------------------------

$myClass = new MyClass();


对于对于myAutoloader 来说,Myclass,就是一个字符串,所以说你可以对它为所欲为,比如说加后缀,有人喜欢.php,有人喜欢.class.php,你只要注册了自动加载类的方法,引擎就会自动调用,不用你在文件开头进行include声明。

用spl_autoload_register 的好处呢?

用spl_autoload_register 之后,你不需要在每一个类中都去重写__autoload方法,并且你可以注册多次

举个例子

spl_autoload_register('MyAutoloader::ClassLoader');
spl_autoload_register('MyAutoloader::LibraryLoader');
spl_autoload_register('MyAutoloader::HelperLoader');
spl_autoload_register('MyAutoloader::DatabaseLoader');

class MyAutoloader
{
public static function ClassLoader($className)
{
//your loading logic here
}

public static function LibraryLoader($className)
{
//your loading logic here
}


对于spl_autoload,简单来说就是__autoload 的默认实现,如果spl_autoload_register()在无参的情况下被调用,就会调用__autoload()。

补充几点,如果说你的所有的文件都放在同一个文件夹内,不仅仅是.php结尾的还有.inc结尾的用户配置文件,可以使用set_include_path()把所有需要的文件防盗php的include路径下,再通过spl_autoload_extensions()列出扩展,例子:

set_include_path(get_include_path().PATH_SEPARATOR.'path/to/my/directory/');
spl_autoload_extensions('.php, .inc');
spl_autoload_register();


参考:http://stackoverflow.com/questions/7651509/someone-explain-spl-autoload-autoload-and-spl-autoload-register
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息