composer 安装不成功_Composer 工具详解

95d4814ab1cbfc3156b1fc567e224be2.png

Composer 功能

composer 是依赖管理工具, 它用来解决如下几个问题:

  • 有一个项目依赖于若干个库

  • 其中一些库依赖于其他库

  • 声明你所依赖的东西

  • 找出哪个版本的包需要安装,并安装它们(将它们下载到你的项目中)

Composer 常用文件
  • composer.json

    关键字含义详解
    name包名monolog/monolog
    description描述
    version版本
    type安装类型- library- project- metapackage- composer-plugin
    license许可协议
    require指定依赖包包名: - 提供商名称- 项目名称- monolog/monolog包版本:-  >, >=, |- *- ~ 下一个重要版本
    require-dev开发测试依赖包--no-dev 参数可以跳过安装这些包
    autoload -> psr-0命名空间到实际路径映射
    autoload -> psr-4命名空间到实际路径映射
    autoload -> classmap引用所有组合
    autoload -> files载入文件
    minimum-stability设定的最低稳定性的版本- dev- alpha- beta- RC- stable
    prefer-stable优先使用更稳定的包版本
    repositories自定义的包资源库- composer- vcs- pear- package按顺序遍历查找
    config配置process-timeoutpreferred-installgithub-protocolsgithub-oauthvendor-dirbin-dircache-dircache-files-dircache-repo-dircache-vcs-dircache-files-ttlcache-files-maxsizeprepend-autoloaderautoloader-suffixoptimize-autoloadergithub-domainsnotify-on-installdiscard-changes
  • composer.lock

    composer install 命令将会检测锁文件是否存在,存在,将下载指定的版本(忽略composer.json 文件中的定义)

    如果不存在 composer.lock 文件, composer 将读取 composer.json 并创建锁文件。

    如果更新版本,使用 composer update, 这将获取最新匹配版本,并新建锁文件。

composer 常用命令
命令含义
composer list获取帮助信息
composer init以交互方式填写 composer.josn 文件信息
composer search根据关键字查找依赖包 (http://packagist.org 上查找)
composer require引入、安装依赖包。等同于编辑 composer.json 文件,然后执行 install 命令
composer install安装 composer.json 中声明的依赖包
composer update更新依赖包。等同于删除 composer.lock 文件,然后执行 install
composer remove移除指定的包依赖
composer clear清除 composer 缓存包
composer show查看安装的依赖包信息。
composer validate检测 composer.json 文件是否有效
composer self-update将 composer 工具更新到最新版本
composer create-project基于 composer 创建一个新的项目
composer dumpautoload生成 autoload 配置信息
Composer 自动加载原理

通过命名空间转换成对应目录的文件, 然后把 loadClass() 函数注册到 PHP 的 SPL 函数堆栈中, 每当 PHP 遇到不认识的的命名空间时, 就会调用函数堆栈中的每个函数, 直到加载命名空间成功。具体的实现分为了如下四个阶段:

  • 启动阶段

    • 加载启动文件和函数

  • 初始化阶段

    • 顶层命名空间和文件目录的映射

  • 注册阶段

    • 顶层以下命名空间和文件目录的映射

    • 类文件的加载

    • 注册函数到 spl_autoload_register 中

  • 运行阶段

    • 查找类并执行

因此, 只需在应用文件中,添加如下代码, 就可以实现代码的自动加载

require 'vendor/autoload.php';
Composer 自动加载实现
  1. 启动阶段

    执行 autoload.php

    # autoload.phprequire_once __DIR__ . '/composer/autoload_real.php';return ComposerAutoloaderInitc6ccc601ff2058fdea354619c8fd4fea::getLoader();
  2. 初始化阶段

    执行 autoload_real.php

     # autoload_real.php public static function getLoader() {     # 构造单例     if (null !== self::$loader) {         return self::$loader;     }     # 注册 「类加载」 类     spl_autoload_register(array('ComposerAutoloaderInitc6ccc601ff2058fdea354619c8fd4fea', 'loadClassLoader'), true, true);     self::$loader = $loader = new \Composer\Autoload\ClassLoader();     spl_autoload_unregister(array('ComposerAutoloaderInitc6ccc601ff2058fdea354619c8fd4fea', 'loadClassLoader'));     # 核心类 初始化     $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());     if ($useStaticLoader) {         require_once __DIR__ . '/autoload_static.php'; call_user_func(\Composer\Autoload\ComposerStaticInitc6ccc601ff2058fdea354619c8fd4fea::getInitializer($loader));     } else {         $map = require __DIR__ . '/autoload_namespaces.php';         foreach ($map as $namespace => $path) {             $loader->set($namespace, $path);         }         $map = require __DIR__ . '/autoload_psr4.php';         foreach ($map as $namespace => $path) {             $loader->setPsr4($namespace, $path);         }         $classMap = require __DIR__ . '/autoload_classmap.php';         if ($classMap) {             $loader->addClassMap($classMap);         }     }     # 注册 类     $loader->register(true);     if ($useStaticLoader) {         $includeFiles = Composer\Autoload\ComposerStaticInitc6ccc601ff2058fdea354619c8fd4fea::$files;     } else {         $includeFiles = require __DIR__ . '/autoload_files.php';     }     foreach ($includeFiles as $fileIdentifier => $file) {         composerRequirec6ccc601ff2058fdea354619c8fd4fea($fileIdentifier, $file);     }     return $loader; }
    1. 注册 「类加载」 类

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

创建 ClassLoader 类, 该类是核心类, 完成了 命名空间和文件目录的映射, 类文件的加载, 类的生成等多种功能。

  2 类文件配置信息的加载

$map = require __DIR__ . '/autoload_namespaces.php';foreach ($map as $namespace => $path) {    $loader->set($namespace, $path);}$map = require __DIR__ . '/autoload_psr4.php';foreach ($map as $namespace => $path) {    $loader->setPsr4($namespace, $path);}$classMap = require __DIR__ . '/autoload_classmap.php';if ($classMap) {    $loader->addClassMap($classMap);}
  • autoload_namespaces.php

    return array(    'HTMLPurifier' => array($vendorDir . '/ezyang/htmlpurifier/library'),    'Diff' => array($vendorDir . '/phpspec/php-diff/lib'),    'Behat\\Gherkin' => array($vendorDir . '/behat/gherkin/src'),);

    文件中直接定义了, 顶级命名空间和文件目录的映射关系。

  • autoload_psr4.php

    return array(    'yii\\swiftmailer\\' => array($vendorDir . '/yiisoft/yii2-swiftmailer/src'),    'yii\\gii\\' => array($vendorDir . '/yiisoft/yii2-gii/src'),    'yii\\faker\\' => array($vendorDir . '/yiisoft/yii2-faker'),    'yii\\debug\\' => array($vendorDir . '/yiisoft/yii2-debug/src'),    'yii\\composer\\' => array($vendorDir . '/yiisoft/yii2-composer'),    'yii\\bootstrap\\' => array($vendorDir . '/yiisoft/yii2-bootstrap/src'),    'yii\\' => array($vendorDir . '/yiisoft/yii2'),);

    文件中直接定义了, 顶级命名空间和文件目录的映射关系

  • autoload_classmap.php

    return array(    'Codeception\\Exception\\ExternalUrlException' => $vendorDir . '/codeception/lib-innerbrowser/src/Codeception/Exception/ExternalUrlException.php',    'Codeception\\Lib\\Connector\\Yii2' => $vendorDir . '/codeception/module-yii2/src/Codeception/Lib/Connector/Yii2.php',    )

    文件中直接定义了, 命名空间和文件的映射关系

  1. 注册阶段

    # 注册 类$loader->register(true);public function register($prepend = false){    spl_autoload_register(array($this, 'loadClass'), true, $prepend);}

    通过 spl_autoload_register 把所有函数注册的 PHP 环境中

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

    另外,  autoload_files.php 中, 定义了所有的全局函数的文件

    return array(    '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',    '0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',)
  2. 运行阶段

    如果代码中运行 new phpDocumentor\Reflection\Element(),PHP 会通过 SPL_autoload_register 调用 loadClass -> findFile -> findFileWithExtension 这样的机制, 去查找类所在的文件,并加载类到内存中。具体操作如下:

     '__DIR__/../phpdocumentor/reflection-common/src + substr(phpDocumentor/Reflection/Element.php,25)'
  • 如果失败,则利用 fallbackDirsPsr4 数组里面的目录继续判断是否存在文件

  • 最后, 加载查找到的类到内存中。

  • 将 \ 转为文件分隔符/,加上后缀php,变成 $logicalPathPsr4, 即 phpDocumentor/Reflection//Element.php;

  • 利用命名空间第一个字母p作为前缀索引搜索 prefixLengthsPsr4 数组,查到下面这个数组:

    'p' => array (    'phpDocumentor\\Reflection\\' => 25,    'phpDocumentor\\Fake\\' => 19, )

    遍历这个数组,得到两个顶层命名空间 phpDocumentor\Reflection\ 和 phpDocumentor\Fake\

  • 在这个数组中查找 phpDocumentor\Reflection\Element,找出 phpDocumentor\Reflection\ 这个顶层命名空间并且长度为25。

  • 在prefixDirsPsr4 映射数组中得到phpDocumentor\Reflection\ 的目录映射为:

    'phpDocumentor\\Reflection\\' => array (     0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src',     1 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src',     2 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src',),

    遍历这个映射数组,得到三个目录映射;

  • 查看 “目录+文件分隔符//+substr($logicalPathPsr4, $length)”文件是否存在,存在即返回。这里就是

Composer 管理自动加载
# composer.json{    "autoload": {        "psr-4": {"Acme\\": "src/"}    }}

composer.json 文件中添加 autoload 映射关系, 并通过命令 composer dumpautoload 可自动添加配置信息到文件 autoload_psr4.php 中

Composer 常用网站
  1. 官网

    https://getcomposer.org/

    https://www.phpcomposer.com/

  2. 依赖包库

    https://packagist.org/

Composer 配置阿里云站点
$ composer clear // 一定要清空历史数据$ composer config --unset repos.packagist  // 一定要取消官网库,否则更新速度很慢$ composer config repo.packagist composer https://mirrors.aliyun.com/composer/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值