前言
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!";
}
}
上面我们是手动进行的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();
classmap
classmap指令告诉php去指定的目录中搜索需要加载的类文件
composer.json
{
"name": "inclu/autoload",
"autoload": {
"classmap": ["lib"]
}
}
再次运行composer dump-autoload
依然可以正常运行
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
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
references: