composer 自动加载 这篇写了自动加载及自定义类使用 psr4 加载。下面介绍下另两种自动加载的方式。1. classmap. 2 files

classmap 方式

同样先创建一个 classmap 的目录结构

1
2
3
4
5
6
7
Classmap
├── Cat
│   └── Cat.php
├── Dog
│   └── Dog.php
└── Other
    └── Person.php
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Person.php
<?php

class Person
{
    function __construct()
    {
        echo "person";
    }
}
# Cat.php
<?php

class Cat
{
    function __construct()
    {
        echo "cat";
    }
}

# Dog.php
<?php

class Dog
{
    function __construct()
    {
        echo "dog";
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# composer.json
{
	"name": "caoayu/composer",
	"description": "composer",
	"require": {
		"monolog/monolog": "^2.2"
	},
	"autoload": {
		"classmap": [
			"Classmap"
		]
	}
}

生成自动加载文件

1
composer dump-autoload

测试

1
2
3
4
5
6
7
8
# test.php
<?php

require 'vendor/autoload.php';

$dog = new Dog();
$person = new Person();
# 执行 php test.php 输出 dog person

可以看到,这次我们并没有使用命名空间跟目录进行一一对应,只是将类目录放在了 classmap 的数组中,在 autoload_classmap.php 中可以看到映射关系。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# autoload_classmap.php
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Cat' => $baseDir . '/Classmap/Cat/Cat.php',
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'Dog' => $baseDir . '/Classmap/Dog/Dog.php',
    'Person' => $baseDir . '/Classmap/Other/Person.php',
);

当然我们也可以给类定义命名空间,并且命名空间的名字并不一定要跟目录名对应,如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Other/Person.php
<?php
namespace XXX;
class Person
{
    function __construct()
    {
        echo "person";
    }
}
# 加入了命名空间后需要更新自动加载文件 composer dump-autoload

# autoload_classmap.php
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Cat' => $baseDir . '/Classmap/Cat/Cat.php',
    'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
    'Dog' => $baseDir . '/Classmap/Dog/Dog.php',
    'XXX\\Person' => $baseDir . '/Classmap/Other/Person.php',
);

# test.php
<?php

require 'vendor/autoload.php';
$person = new XXX\Person();

可以看到,classmap 的方式比较灵活,不拘束与目录与命名空间的约束。同时,这种方式也有他的弊端。

使用 classmap 的方式自动加载,可能会对代码提示及跳转支持的不太友好,也对于我们寻找对应的文件不太直观,因为这种方式与目录不要求一一对应,太自由。所以使用 classmap 尽量不适用命名空间,但是如果对代码的目录及结构要求比较嗷规范的话,使用这种方式是很方便的。

Files 方式

有时,我们需要定义一些全局的助手函数,就可以使用这种方式来完成。将一个或多个函数写入到一个或多个文件中,并使用自动加载文件的方式将函数加载进来。

项目下新建文件并修改 composer.json 文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# functions1.php
function sayHello($name,$word){
    echo $name.$word;
}

# composer.json
{
	"name": "caoayu/composer",
	"description": "composer",
	"require": {
		"monolog/monolog": "^2.2"
	},
	"autoload": {
		"files": [
			"functions1.php"
		]
	}
}

生成自动加载文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
composer dump-autoload
# 自动更新下面的文件
# autoload_files.php
<?php

// autoload_files.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    '4e9008cccfad63926f24a3a644b23b82' => $baseDir . '/functions1.php',
);

调用

1
2
3
4
5
6
#test.php
<?php

require 'vendor/autoload.php';

echo sayHello('lisa',' hello');

正常输出说明自动加载成功。


这个系列简单介绍了 composer 及自动加载的机制。在各 php 框架中,都会有很多自动加载的使用,但是其实使用的都是 composer 的自动加载,所以将 composer 的自动加载掌握后,对于 php 框架的理解会更深入一些。