composer 指令集和项目配置文件解析

2020-03-30T15:49:00

查看版本号

composer -V[--version]

require 关键词

第一个(并且经常唯一一个)你需要在 composer.json 配置文件中明确规定的东西就是 require 关键词。配置文件列出项目的依赖包和和可能包含的元数据。

{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}

正如你看到的,require 携带一个映射依赖包名称到版本限定(比如 1.0.*)的对象。

composer 使用这个信息在你使用 repositories 关键词注册的依赖包仓库或者在默认的依赖包仓库 Packagist 去搜索准确的文件集合。在上面的例子中,既然在 composer.json 中没有已经注册其他的仓库,就会默认 monolog/monolog 依赖包是注册在 Packagist 中的。

[notice] 关于 Packagist 和 repositories 仓库的概念可以点击 packagistrepos 查看。[/notice]

包名

包名由一个 vendor 名和项目名组成。经常出现会项目名相同的情况,而 vendor 名存在的目的就是防止命名冲突。举个例子,两个不同的人都可以创建一个叫 json 的库。一个可能会叫 igorw/json,另一个可能叫 seldaek/json

阅读更多有关发布包和包命名规则可以看这里。(注意,你也可以将 “平台包” 定义为依赖包,这样你可以依赖某些服务软件版本,查看更多关于“平台包”)

包版本限定

在我们的例子中,我们将请求版本限定为 1.0.* 的 Monolog 包。这表示任何 1.0 开发分支,或者大于等于 1.0 并小于 1.1 的任何版本(>=1.0 <1.1)。

请阅读 版本 了解更多关于版本,版本之间如何互相关联和关于版本限定的深入详细的信息。

[notice]
composer 是如何下载正确的文件的?当你在 composer.json 中明确规定一个依赖的时候,composer 首先你之前请求过的包名并在你使用 repositories 注册的所有仓库中搜索。如果你还没有注册过任何的仓库,或者它没有找到你所明确规定的包名,它会回撤到 Packagist。
[/notice]
[notice]
当 composer 找到了正确的包,不管是在 Packagist 中还是在一个你定义的仓库中,它接着会利用包的版本控制系统(VCS)的版本特征(比如,分支或者是标记)尝试找到与你定义的版本限定最匹配的版本。一定要阅读版本和包解决方案的版本文章
[/notice]
[notice]
注意:当你尝试引入一个包但 composer 抛出关于包稳定性的错误,这说明你规定的包版本没有满足你默认的最低稳定性的要求。在你的 VCS 中搜索有效包版本的时,默认只考虑稳定的发布版。
[/notice]

安装依赖

为了给你的项目安装定义的依赖,执行 install 指令。

php composer.phar install
[or directly] composer install

当你执行这个指令时,会发生两件事:

  • 不存在 composer.lock 时的安装

如果你之前从来没有执行过这个指令并且现在没有 composer.lock 文件,composer 会简单解析所有你在 composer.json 文件中列出的依赖,并下载这些依赖文件的最新版本到你项目下的 vendor 目录下(vendor 目录是一个项目中第三方代码按照惯例存放的位置)。在我们上面的例子中,最终会以 vendor/monolog/monolog/ 下的 Monolog 源代码结束。如果 Monolog 列出任何的依赖,这些依赖也会被放在 vendor 下的文件夹中。

[notice]提示:如果你的项目使用 git,那么很有可能你会想把 vendor 添加到 .gitignore 中。你肯定不会想要把所有第三方代码添加到你的版本仓库中的。[/notice]

当 composer 结束安装之后,它会写入下载的所有包和包具体的版本到 composer.lock 文件中,锁定项目依赖到这些具体的版本。你应该把 composer.lock 文件提交到你的项目仓库中,这样所有在这个项目中工作的人但会锁定相同版本的依赖。

  • 存在 composer.lock 时的安装

这把我们带到第二个场景。如果当你运行 composer install 的是时候 composer.lock 以及 composer.json 已经存在,它意味着或者你之前执行过 install 指令,或者项目中的其他某个人执行过 install 指令,并且将 composer.lock 提交到项目中(这是好的)。

不管哪种情况,在 composer.lock 已存在时执行 install 指令会解析并安装所有你在 composer.json 中列出的依赖,但 composer 会使用 composer.lock 中列出的精确版本来确保项目中所有人拿到的包版本是一直的。最终你会得到所有在 composer.json 中请求的依赖,但他们可能不会是最新可获得的版本(有些在 composer.lock 中列出的依赖子文件创建后可能已经发布了更新的版本)。这是故意的,这能确保你的项目不会因为依赖上发生的未知变化而挂掉。

  • 提交 composer.lock 到版本控制

提交 composer.lock 到版本控制很重要,这会使得任何创建项目的人使用和你一样的依赖。你的 CI 服务器(持续集成服务器),生产机器,你团队中其他的开发者,所有东西和所有的人运行相同的依赖,这会减少出现只影响到部分部署的 bugs 的可能性。即使你单独开发,在 6 个月后重新安装项目,你可以很自信依赖安装任然有效,即使自那以后你的依赖包发布了很多个新版本。(查看下面关于 update 指令的注意点。)

更新依赖到他们最新的版本

就像上面提到的,composer.lock 文件防止你自动获取到你的依赖包的最新版本。为了更新到最新的版本,使用 update 指令。它可以取回最新适配的版本(根据你的 composer.json 文件)并使用最新版本更新锁文件。(这相当于是删除了 composer.lock 文件再执行一次 install 指令。)

php composer.phar update

[notice]注意:如果 composer.json 发生了可能会影响到依赖解决的改变后,composer.lock 一直没有更新的话,在执行 install 指令时会展示一个警告[/notice]

如果你只想安装或更新一个依赖,可以把它添加到白名单列表

php composer.phar update monolog/monolog [...]

[notice]注意:对于库文件没有必要更新 composer.lock 文件,具体查看 Libraries - Lock file[/notice]

Packagist

Packagist 是主要的 composer 仓库。一个 composer 仓库基本就是一个包源:一个你可以获取到依赖包的地方。Packagist 旨在成为所有人使用的中央仓库。这意味着你可以自动 require 依赖那里可获得的任何包,而不需要进一步明确规定 composer 寻找包的地方。

如果你去 Packagist 网站 (packagist.org),你可以浏览和搜索包。

任何使用 composer 的开源项目都建议发布他们的包到 Packagist 上。一个库(library )不需要放到 Packagist 来让 composer 使用,但这样做会让其他开发者更快的找到和采用。

平台包(Platform packages)

composer 有平台包,相比安装再系统中但不是通过 composer 安装的东西,平台包是虚拟的包。这包括 PHP 本身,PHP 扩展和一些系统类库。

  • php 代表用户的 php 版本,允许你使用一些限定,比如说版本 ^7.1。规定 64 bit 位版本的 php,你可以规定 php-64bit 的包。
  • hhvm 代表 HHVM 运行态的版本,并且允许你使用一个限定,比如 ^2.3
  • ext- 允许你规定 PHP 扩展(包括核心扩展)。这里的版本可以完全不同,所以通常设置限制为 * 比较好。举个扩展包的例子:ext-gd
  • lib- 允许在 PHP 使用的库版本上做一些限定。这些都是可获取到的:curliconv, iculibxmlopensslpcreuuidxsl

你可以使用 show --platform 来得到一个你本地可获取到的平台包列表。

自动加载(Autoloading)

对于明确定义自动信息的类库,Composer 生成一个 vendor/autoload.php 文件。你可以简单引入(include)这个文件并开始使用那些类库提供的类,而不需要额外操作。

require __DIR__ . '/vendor/autoload.php';

$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

你甚至可以通过在 composer.json 添加一个 autoload 定义域来添加自己代码到自动加载器中。

{
    "autoload": {
        "psr-4": {"Acme\\": "src/"}
    }
}

Composer 会给 Acme 命名空间注册一个 [PSR-4][10] 自动加载器。

你可以定义一个从命名空间到目录的映射关系。src 目录应该是在你的根目录,跟 vendor 目录所在是同一级。举个例子,文件名可以是包含 Acme\Foo 类的 src/Foo.php

在添加 autoload 定义域之后,你得重新运行一次指令:

php composer.phar dump-autoload

这个指令会重新生成一个 vendor/autoload.php 文件。查看 dump-autoload 小节获取更多信息。

引入那个文件还会返回一个自动加载器(autoloader)实例,这样你就可以在一个变量中存储引入调用的返回值并添加更多的命名空间。这对于在测试套件中自动加载类会很有帮助,比如说:

$loader = require __DIR__ . '/vendor/autoload.php';
$loader->addPsr4('Acme\\Test\\', __DIR__);

除了 PSR-4 的自动加载,Composer 还提供 PSR-0, classmap 和 files 的自动加载。查看 autoload 指南获取更多信息。

也可以在 optimizing the autoloader 查看文档。

[notice]Composer 提供自己的自动加载器。如果你不想用那一个,你可以引入 vendor/composer/autoload_*.php 文件,这个文件会返回让你配置自己的自动加载器的关联数组。[/notice]

翻译自 :Basic usage - Composer

当前页面是本站的「Baidu MIP」版。发表评论请点击:完整版 »