PHP的自动加载autoload和spl_autoload_register
一、自动加载的实现
-
__autoload
PHP早期支持的版本。具体细节参加官方文档。
如果你需要实现自动加载后,可以通过定义这个函数来启用。
就是在你的PHP脚本中定义这样的一个函数,把加载逻辑都写在里面。比如这样:function autoload($className){ $name = strtolower($className); $path= "./includes/{$name}.php"; if(file_exists($path)){ require_once($path); }else{ die("the file {$className} could not be found"); } }
这样就会自动加载当前目录下的
includes
下的文件了。
类似用法经常在私人项目,或者说是单一项目的框架中见到,为什么呢?因为你只能定义一个__autoload function
,在多人开发中做不到不同的开发者使用不同的自定义的autoloader,除非大家都提前说好了,都使用一个__autoload
,涉及到改动了就进行版本同步,这很麻烦。 -
spl_autoload_register
于是,为了解决上面的问题,在PHP的7.2版本,引入了spl_autoload_register
。具体细节参加官方文档。
它不再是让你定义一个函数了。是官方定义的好的函数,你只需要调用它,把你的加载逻辑写在它的匿名函数即可。使用方法如下:
spl_autoload_register(function($className){ $name = strtolower($className); $path= "./includes/{$name}.php"; if(file_exists($path)){ require_once($path); }else{ die("the file {$className} could not be found"); } });
这样就可以完成了自动加载的实现。而且,定义多个autoloader。
使用的访问有以下几种:- 使用匿名函数
// 使用匿名函数来autoload spl_autoload_register(function($className){ require_once('...'); })
- 使用全局函数
// 使用全局函数 function custom(){ require_once('...'); }
- 使用一个class当中的static的方法
// 使用一个class当中的static的方法 class MyCustomAutoloader { public static function myLoader($className){ require_once('...'); } } // 传递array进来,第一个是class名,第二个方法名 spl_autoload_register(['MyCustomAutoloader', 'myLoader']);
- 甚至可以用在实例化的object上
// 甚至可以用在实例化的object上 class MyCustomAutoloader { public function myLoader($className){ require_once('...'); } } $object = new MyCustomAutoloader; spl_autoload_register([object, 'myLoader']);
具体以官方文档为主。
- 使用匿名函数
二、自动加载的优点
自动加载不同于require
和include
。autoload机制是lazy loading。即是并不是你一运行就给你调用所有的文件,而是只有你用到了哪个,比如说new了哪个文件以后,才会通过autoload机制去加载相应文件。
为了提高程序的性能,很多大型的框架都是使用这种加载方式。比如laravel中就大量使用这个方式。