返回
顶部

前言

php的autoload机制对于大型项目来说尤为重要,因为随着项目体积的增大,需要用到的类也会随之增多,如果全部都靠手动进行include,一则浪费精力,二来会加载很多不必要的类,造成内存资源的浪费

因此php引入了autoload机制,来解决这个问题

引子

php提供了spl_autoload_register方法来让我们注册自己的自动加载方法

被注册的方法将会在php找不到你所使用的类的时候进行调用,然后把相应的类文件include到当前文件中

一个简单的例子

index.php

<?php
function custom_autoload_function($class) {
    include 'lib\\' . $class .'.php';
}

spl_autoload_register('custom_autoload_function');

$obj  = new Fuck();

我们在当前目录下创建lib目录,然后新建Fuck.php

<?php
class Fuck {
    function __construct() {
        echo "fucking autoload test!";
    }
}

1622964660633

上面我们是手动进行的autoload方法的注册,下面我们使用composer的自动加载功能

composer自动加载

大致有四种类型

  • file
  • classmap
  • psr-0
  • psr-4

下面我们通过实例来进行讲解

在家目录创建~\phplearning\autoload目录,然后执行composer init初始化一个composer项目,全部默认即可

file

修改composer.json如下

{
    "name": "inclu/autoload",
    "autoload": {
        "files": ["lib/Foo.php", "lib/Bar.php"]
    }
}

然后执行composer dump-autoload命令,会自动创建出vendor目录并生成其所需的各种文件

之后,我们只需要在源文件中加入下面这行代码即可:

include 'vendor\autoload.php';

上面composer.json中的file指令添加了一个文件列表,当php找不到你调用的类的时候就会从这个列表中依次查询,直到找到你所需的类

因此我们建立lib目录并创建Foo.php以及Bar.php文件

Foo.php

<?php

class Foo {
    function __construct() {
        echo "Foo autoload test!";
    }
}

Bar.php

<?php

class Bar {
    function __construct() {
        echo "Bar autoload test!";
    }
}

index.php

<?php
include 'vendor\autoload.php';

$obj  = new Foo();
echo "<br />";
$obj  = new Bar();

1622965209112

classmap

classmap指令告诉php去指定的目录中搜索需要加载的类文件

composer.json

{
    "name": "inclu/autoload",
    "autoload": {
        "classmap": ["lib"]
    }
}

再次运行composer dump-autoload

1622965209112

依然可以正常运行

psr-0

php的psr-0规范定义了命名空间的相关规则,详细信息请自行google,在此不做讲解

composer.json

{
    "name": "inclu/autoload",
    "autoload": {
        "psr-0": {
            "Mother\\Fucker\\": "lib"
        }
    }
}

psr-0指令规定了Mother\Fucker命名空间对应lib目录,也就是说,该命名空间下的类都位于lib\Mother\Fucker目录下,可以看到这里命名空间和目录结构有一个明显的一一对应的关系

lib\Mother\Fucker\Fuck.php

<?php
namespace Mother\Fucker;

class Fuck {
    function __construct() {
        echo "motherfucker PSR-0 autoload test!";
    }
}

index.php

<?php
include 'vendor\autoload.php';

use Mother\Fucker\Fuck;

$obj  = new Fuck();

重新运行composer dump-autoload

1622965862076

PSR-4

composer.json

{
    "name": "inclu/autoload",
    "autoload": {
        "psr-4": {
            "Mother\\Fucker\\": "lib"
        }
    }
}

psr-4和psr-0的写法是一样的,只有一点不同,就是,命名空间不需要和目录结构对应

上面的psr-4指令规定了lib目录下的类文件都是在Mother\Fucker命名空间下的

lib\Fuck.php

<?php
namespace Mother\Fucker;

class Fuck {
    function __construct() {
        echo "motherfucker PSR-4 autoload test!";
    }
}

重新运行composer dump-autoload

1622966054181

references: