深入理解 spl_autoload , __autoload 以及 spl_autoload_register
2016-08-01 16:50
316 查看
这篇文章将从初学者到进阶同学的角度,循序渐进的谈论一下 PHP 中的自动加载类,以及深入理解 spl_autoload , __autoload ,spl_autoload_register。
除此以外,PHP还有一个自动加载类机制,如果说PHP找不到类的定义(比如说你在A.class.php 中想要new 一个B 类),就会触发自动加载类。
本例尝试分别从 MyClass1.php 和 MyClass2.php 文件中加载 MyClass1 和 MyClass2 类。
面试题:如果非要说上面的代码有地方可以改进,你说说是哪里?
没有必要使用require_once 或者是 include_once,因为只有在类找不到的时候才会出发自动加载类。
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.
官方文档中更建议使用
这个说的并不是很明确,我再解释一下。
允许你注册多个方法,或者静态方法,PHP引擎会把他们放到栈/队列中,当你“new” 一个类的时候,会顺序的调用。
举个例子
对于对于myAutoloader 来说,Myclass,就是一个字符串,所以说你可以对它为所欲为,比如说加后缀,有人喜欢.php,有人喜欢.class.php,你只要注册了自动加载类的方法,引擎就会自动调用,不用你在文件开头进行include声明。
用spl_autoload_register 的好处呢?
用spl_autoload_register 之后,你不需要在每一个类中都去重写__autoload方法,并且你可以注册多次
举个例子
对于spl_autoload,简单来说就是__autoload 的默认实现,如果spl_autoload_register()在无参的情况下被调用,就会调用__autoload()。
补充几点,如果说你的所有的文件都放在同一个文件夹内,不仅仅是.php结尾的还有.inc结尾的用户配置文件,可以使用set_include_path()把所有需要的文件防盗php的include路径下,再通过spl_autoload_extensions()列出扩展,例子:
参考:http://stackoverflow.com/questions/7651509/someone-explain-spl-autoload-autoload-and-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
相关文章推荐
- PHP autoload与spl_autoload自动加载机制的深入理解
- PHP autoload与spl_autoload自动加载机制的深入理解
- __autoload机制详解以及与spl_autoload_register的区别
- PHP autoload与spl_autoload自动加载机制的深入理解
- 详解spl_autoload_register()函数以及自动加载不同目录的类
- 深入理解.Net中的内存释放,以及有关的注意事项
- PHP自动加载类—__autoload()和spl_autoload_register()
- spl_autoload_register 让类在需要的时候自动加载
- php的spl_autoload_register与zend framework的Zend_Loader_Autoloader
- 深入理解linux下rc.d/目录文件以及程序开机自启动
- PHP自动加载类—__autoload()和spl_autoload_register() (补充)
- 深入理解.Net中的内存释放,以及有关的注意事项
- 深入理解构造函数和析构函数以及父类和子类的部分关系
- initramfs 深入理解, 以及initramfs与initrd的区别
- PHP函数spl_autoload_register()用法和__autoload()介绍
- 魔法方法__autoload失效的解决办法spl_autoload_register()
- PHP spl_autoload_register实现自动加载研究
- 12-31--PHP函数spl_autoload_register实现自动加载研究
- 深入理解C++对象模型-成员函数的本质以及虚函数的实现(非虚继承)
- php spl_autoload_register函数接口