Composer自动加载机制学习——classmap

上一篇《Composer自动加载机制学习——File》分析了file的加载方式,本篇接着讨论classmap的自动加载方式。

新建两个类文件

首先在目录下新建一个文件夹:libs,在libs里面新建两个php文件,分别为:ClassA.phpClassB.php
ClassA.php代码如下:

<?php
class ClassA
{
    public function test()
    {
        echo "ClassA::test\n";
    }
}

ClassB.php代码如下:

<?php
class ClassB
{
    public function test()
    {
        echo "ClassB::test\n";
    }
}

修改composer.json文件

回到网站根目录,修改composer.json,在autoload中新增键:classmap,值为["libs/"]

...
    "autoload":{
        "classmap": ["libs/"]
    }
...

修改后执行命令:composer dump-autoload重新生成自动加载文件

修改index.php

修改index.php代码为:

<?php
require 'vendor/autoload.php';

$ca = new ClassA();
$ca->test();

$cb = new ClassA();
$cb->test();

执行程序,结果为:

可以看出,classmap的方式,只需要指定类文件所在的目录即可自动加载,这在类文件多的时候,非常方便。

打开autoload_classmap.php文件,可以看到如下代码:

<?php

// autoload_classmap.php @generated by Composer

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

return array(
    'ClassA' => $baseDir . '/libs/classA.php',
    'ClassB' => $baseDir . '/libs/classB.php',
);

该文件返回了一个数组,数组的键是类的名称,值则为类所在的磁盘路径。
当调用不存在的类时,composer首先会调用ClassLoader.php文件中的loadClass方法,参数为未找到的类的名字。

public function loadClass($class)
{
    if ($file = $this->findFile($class)) {
        includeFile($file);

        return true;
    }
}

loadClass函数中通过findFile方法来查找类文件是否存在,如果存在则include进来。

以上展示的时没有命名空间的情况,由命名空间也一样,例如有两个classA.php文件,在不同的命名空间内。
在libs目录下新建一个MyClass文件夹,然后在MyClass文件夹新建Test1文件夹和Test2文件夹。
在Test1文件夹新建一个ClassA.php文件,内容如下:

<?php
namespace MyClass\Test1;

class ClassA
{
    public function test()
    {
        echo "MyClass\\Test1\\ClassA::test\n";
    }
}

在Test2文件夹新建一个ClassA.php文件,内容如下:

<?php
namespace MyClass\Test2;

class ClassA
{
    public function test()
    {
        echo "MyClass\\Test2\\ClassA::test\n";
    }
}

修改index.php文件,内容如下:

<?php
require 'vendor/autoload.php';

$ca = new \MyClass\Test1\ClassA();
$ca->test();

$cb = new \MyClass\Test2\ClassA();
$cb->test();

运行composer dump-autoload命令更新composer文件。
运行index.php,结果如下:

MyClass\Test1\ClassA::test
MyClass\Test2\ClassA::test

可以看到,每当新增需要自动加载的类文件时,均需要运行composer dump-autoload命令来更新composer文件。因为只有运行composer dump-autoload命令后,autoload_classmap.php文件才会重新把新增的类文件的映射关系更新进去。

参考:
详解composer的自动加载机制:https://blog.csdn.net/zhang197093/article/details/78118491

发表评论

邮箱地址不会被公开。 必填项已用*标注