为什么需要自动加载?
在PHP5之前, 如果需要引入外部的文件,那么需要通过include和require命令。如果只是小项目,那么倒也没什么问题,但是当我们做大型项目的时候,大量的include/require则会有很多缺点:
- 可能造成引入混乱
- 代码必须和文件路径做硬链接,耦合
- 文件中的类可能还未使用到,但是include/require就已经加载进来了
解决方案
在php5之后,zend提供了__autoload函数
function __autoload($classname)
{
var_dump($classname);exit();
}
$obj = new Demo();
结果:Deprecated: __autoload() is deprecated, use spl_autoload_register() instead in /www/php/test_code/autoload.php on line 3
string(4) "Demo"
- 在php7这个函数已经不推荐使用了
- 而且如果所有类的加载逻辑都在__autoload中,逻辑太复杂,难以实现
更好的方法
使用php5提供的sql_autoload_的一类函数,这也是composer的基石
- spl_autoload_register 注册一个自动加载函数
example1:
function my_autoload($classname)
{
var_dump($classname);exit();
}
spl_autoload_register("my_autoload");
$obj = new Demo();
example2:
class MyAutoload
{
function my_autoload($classname)
{
var_dump($classname . 'in class');exit();
}
}
spl_autoload_register(array(new MyAutoload(), 'my_autoload'));
$obj = new Demo();
example3:
class MyAutoload
{
static function my_autoload($classname)
{
var_dump($classname . 'in class');exit();
}
}
spl_autoload_register(array(MyAutoload::class, 'my_autoload'));
$obj = new Demo();
example4:
function my_autoload($classname)
{
var_dump($classname . ' in function');exit();
}
class MyAutoload
{
static function my_autoload($classname)
{
var_dump($classname . ' in class');exit();
}
}
spl_autoload_register(array(MyAutoload::class, 'my_autoload'));
spl_autoload_register("my_autoload");
$obj = new Demo();
- spl_autoload_call 尝试从自动加载队列中加载类。如果存在则加载
class MyAutoload
{
static function my_autoload($classname)
{
var_dump($classname . ' in class');
require './' . $classname . '.php';
}
}
spl_autoload_register(array(MyAutoload::class, 'my_autoload'));
spl_autoload_call("Demo");
$obj = new Demo();
var_dump($obj);
结果(Demo类已存在的情况):
string(13) "Demo in class"(只有一次)
object(Demo)#1 (0) {
}
- spl_autoload($classname) 表示加载某一个类,通过include_path所在的路径加载
spl_autoload("Demo", ".php");
$obj = new Demo();
var_dump($obj);
结果(此时在同目录下,存在Demo.php):
object(Demo)#1 (0) {
}
- spl_autoload_functions 获取自动加载的函数队列
function my_autoload($classname)
{
var_dump($classname . ' in function');exit();
}
spl_autoload_register("my_autoload");
class MyAutoload
{
static function my_autoload($classname)
{
var_dump($classname . ' in class');
require './' . $classname . '.php';
}
}
spl_autoload_register(array(MyAutoload::class, 'my_autoload'));
$result = spl_autoload_functions();
var_dump($result);exit();
结果:
array(2) {
[0]=>
string(11) "my_autoload"
[1]=>
array(2) {
[0]=>
string(10) "MyAutoload"
[1]=>
string(11) "my_autoload"
}
}
- spl_autoload_extensions 设置自动加载文件的后缀, 一般配合spl_autoload函数使用
spl_autoload_extensions('.php');
spl_autoload("Demo");
$obj = new Demo();
var_dump($obj);
结果:
object(Demo)#1 (0) {
}
- spl_autoload_unregister 注销队列中某个自动加载函数, 用法与spl_autoload_register函数类似