0

0

composer自动加载实例分析

小云云

小云云

发布时间:2018-02-26 10:37:14

|

2261人浏览过

|

来源于php中文网

原创

通过在composer.json文件中配置需要加载的类、命名空间,通过执行composer install 命令自动生成类名和对应的类文件的映射,而后通过注册loadClass方法,实现对composer管理的诸多类的自动加载;

如何在composer.json文件中配置类和命名空间 ?

共有四种方式:
psr-0(网上查到的例子和psr-4没有看出太大区别,且已不推荐使用);
psr-4;
class-map;
files;
在composer.json文件中添加以下代码块:

"autoload": {
    "psr-4": {
        "src\\darren\\": "src/",
        "project\\darren\\": "project"
        },
    "files": ["common/Darren.php", "common/Since.php"],
    "classmamp": [lib]
}

测试代码目录结构如下:

common
    Darren.php
    Since.php
lib
    Darren.php
    Since.php
project
    Darren.php
src
    Darren.php
vendor
composer.json
index.php

代码中的命名空间习惯为:目录名/Darren
当我们配置好composer.json文件,并执行compoer install命令后,在vendor/composer目录下会自动生成一些php文件,这些文件实际上记录了类、命名空间和对应的类文件的映射,下面一一举例说明;

PSR-4

如上所述,通过psr-4方式配置了两个命名空间的自动加载,分别是src\daren和projecr\darren;vendor/composer目录下自动生成了autoload_psr4.php文件,具体代码如下所示:

 array($baseDir . '/src'),
'project\\darren\\' => array($baseDir . '/project'),
);
Classmap方式

classmap方式只需要我们配置需要自动加载的目录,compoer会自动扫描目录下的的.php文件或.inc文件中的class,并自动生成这些类和其对应的类文件的映射关系,保存在vendor/composer目录下的autoload_classmap.php文件中,具体代码如下:

 $baseDir . '/lib/Darren.php',
'lib\\since\\Since' => $baseDir . '/lib/Since.php',
);

其中lib\darren为命名空间,Darren为类名;

Files

files方式其实就是手动指定要加载的文件,这通常适用于一些全局的functions,可以将这些functions统一放在一个文件里,然后直接进行加载;
上述的配置文件通过files方式加载了两个文件common/Darren.php和common/Since.php,vendor/composer目录下自动生成了autoload_files.php文件,具体代码如下所示:

 $baseDir . '/common/Darren.php',
'603921ee67f9053beb44a88f05b115d2' => $baseDir . '/common/Since.php',
);
composer是如何实现自动加载的 ?

配置完compoer.json文件,跑完了composer install命令,在文件的开始引用vendor/autolaod.php即可实现类的自动加载,那么composer是如何实现自动加载的呢?


这里先插叙一点php的特性:当调用不存在的类时,系统会自动调用__autoload( )方法来加载相应的类;

举例子说明如下:
我们在index.php文件中调用Darren类中的testAutoload( )方法【Darren类与index.php文件在同级目录】,这里我们没有在index.php文件中引入Darren类,那么肯定是会报错的;但是我们可以重写__autoload( )方法实现Darren类的加载,具体代码如下:

//当调用不存在的类时,系统自动调用__autolaod()查找
function __autolaod($class)
{
    $file = $class . '.php';
    if (is_file($file)) {
        require_once($file);
    }
}
Darren::testAutoload();

我们也可以通过spl_autoload_register( )方法来注册一个其它方法来替代__autoload( );

举例如下:

function loader($class)
{
    $file = $class . '.php';
    if (is_file($file)) {
        require_once($file);
    }
}
spl_autoload_register('loader');
Darren::testAutoload();

这样,loader方法就取代了__autoload;

Difeye-敏捷的轻量级PHP框架
Difeye-敏捷的轻量级PHP框架

Difeye是一款超轻量级PHP框架,主要特点有: Difeye是一款超轻量级PHP框架,主要特点有: ◆数据库连接做自动主从读写分离配置,适合单机和分布式站点部署; ◆支持Smarty模板机制,可灵活配置第三方缓存组件; ◆完全分离页面和动作,仿C#页面加载自动执行Page_Load入口函数; ◆支持mysql,mongodb等第三方数据库模块,支持读写分离,分布式部署; ◆增加后台管理开发示例

下载

接下来我们继续研究composer背后的加载机制,autoload.php中引入了autoload_real.php然后调用了getLoader( )方法,getLoader( )方法具体代码如下:

public static function getLoader()
{
    if (null !== self::$loader) {
        return self::$loader;
    }

    spl_autoload_register(array('ComposerAutoloaderInit0a8197b9e4da93df051721eff8ed7b28', 'loadClassLoader'), true, true);
    self::$loader = $loader = new \Composer\Autoload\ClassLoader();
    spl_autoload_unregister(array('ComposerAutoloaderInit0a8197b9e4da93df051721eff8ed7b28', 'loadClassLoader'));

    $map = require __DIR__ . '/autoload_namespaces.php';
    foreach ($map as $namespace => $path) {
        $loader->set($namespace, $path);
    }

    //整理通过psr-4方式配置的类
    $map = require __DIR__ . '/autoload_psr4.php';
    foreach ($map as $namespace => $path) {
        $loader->setPsr4($namespace, $path);
    }

    //整理通过classmap方式配置的类
    $classMap = require __DIR__ . '/autoload_classmap.php';
    if ($classMap) {
        $loader->addClassMap($classMap);
    }

    //注册实现自动加载的方法
    $loader->register(true);

    //直接引入通过files配置的类
    $includeFiles = require __DIR__ . '/autoload_files.php';
    foreach ($includeFiles as $fileIdentifier => $file) {
        composerRequire0a8197b9e4da93df051721eff8ed7b28($fileIdentifier, $file);
    }

    return $loader;
}

该方法先是创建了一个ClassLoader类的对象,然后加载composer自动生成的那些记录类、命名空间与文件映射关系的文件,调用ClassLoader中的方法对这些文件整理,并将映射关系通过数组保存,数组的键为类名或者命名空间加类名,数组的值为类对应的类文件地址;这里值得注意的一点是,我们通过files配置的那些需要自动加载的类,是直接将类文件引入进来,并不是在调用时才去加载,代码如下:

function composerRequire0a8197b9e4da93df051721eff8ed7b28($fileIdentifier, $file)
{
    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
        require $file;//直接引入类文件
        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
     }
}

ClassLoader类中值得注意的方法:

通过register方法注册loadClass方法,取代__autoload( )方法,实现类的加载

public function register($prepend = false)
{
    spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}

loadClass方法查找类对应的文件,并引入:

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

具体如何查找数组从而得到该类对应的类文件,可以通过xdebug跟一遍代码,并不难理解;

相关推荐:

Thinkphp5 使用composer中seeder播种机

如何用 composer 造轮子

Composer是怎么安装的?

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

1709

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1139

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1041

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

948

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1396

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1228

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1439

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1303

2023.11.13

虚拟号码教程汇总
虚拟号码教程汇总

本专题整合了虚拟号码接收验证码相关教程,阅读下面的文章了解更多详细操作。

25

2025.12.25

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
第二十四期_PHP8编程
第二十四期_PHP8编程

共86课时 | 3.4万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 2.3万人学习

第二十三期_PHP编程
第二十三期_PHP编程

共93课时 | 6.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号