Composer 的基础用法

作者:代码可乐    发布日期:2018年5月20日


Composer 是一个 PHP 的依赖管理工具。通过本文,我介绍一下 Composer 的基础用法。想了解 Composer,可以先阅读 《Composer 介绍和安装指南》

Monolog 是一个流行的 PHP 类库,用于在项目中记录日志,它实现了 PSR-3 规范。我们就以在项目中安装它为例,来看看如何使用 Composer。

首次安装依赖包

我们先看一下,首次通过 Composer 安装依赖包的场景。

创建配置 composer.json

composer.json 是一个 JSON 格式的配置文件,用来定义当前项目的依赖和其它一些元数据。

我们在项目根目录创建一个 composer.json 文件,内容如下:

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

其中字段 require 定义了当前项目依赖的包信息,标明了包名 monolog/monolog,以及包的版本约束:1.0.*

如何理解包的定义

一个包含了 composer.json 配置文件的项目,即是一个 Composer 包。如果配置中定义了包自身的名称(注:通过配置属性 name 实现),那么通常是一个包含类库的包,可以发布到仓库中,可以作为其它包的依赖,这类包是我们最常见的包的说法。而另外一种包,可以不定义名称,那么就是一个直接作为项目运行的包,通常不会被其它包依赖,我们直接称之为项目,如本文中的项目。

包的命名

包名由供应商(即作者)名称和项目名称组成,用正斜杠分割。两者可以相同也可以不同,用来防止命名冲突。

包的版本约束

上述例子中,包的版本约束为 1.0.*,意味着要求安装的依赖包的版本号 >= 1.0< 1.1

安装依赖包

运行命令:

composer install

这时,Composer 会根据配置中定义的依赖信息,从远程仓库下载相应的依赖包,且满足版本约束的最新版本号(比如 1.0.23)。然后将其保存到当前目录下的 vendor 目录里。上述例子中,Monolog 类库的源代码将保存到目录 /vendor/monolog/monolog 中。

关于 vendor 目录

项目中的 vendor 目录,通常用来存在第三方开发的代码。

另外,如果 Monolog 包也依赖了其它包,那这些包也会被安装。

最后,Composer 会将本次安装的、所有的包名称,及其精确版本号(如上文的例子,1.0.23),写入到当前目录下的文件 composer.lock 中。

Composer 是如何从远程仓库下载依赖包的

Composer 会优先从自定义的仓库(可选,可以通过 composer.json 配置)中,搜索指定的包(名)。如果没找到,再到主仓库 Packagist 中搜索。找到指定包后,再查询此包代码仓库上的分支或标签信息,找到最佳匹配版本。另外,Composer 默认只会检索稳定版本。

Packagist 介绍

仓库其实是一个包安装源。Packagist 是 Composer 的主仓库,也是默认仓库。另外,也可以直接访问 Packagist 站点,在线浏览和搜索包。

更新依赖包

我们先来看一下,如何更新依赖包。

每过一段时间,依赖包都会发布新版本,当我们需要更新已安装的依赖包到最新版本的时候,运行:

composer update

更新完成后,Composer 也会将最新的精确版本号更新到 composer.lock 文件。

我们也可以只更新指定的依赖包,比如:

composer update monolog/monolog

通过 composer.lock 安装依赖包

我们再回来看看,另外一个依赖包安装场景:已经存在 composer.lock 文件。

composer.lock 的作用

如上文所述,composer.lock 保存了当前项目的所有包名称、及其精确版本号。当前任何依赖版本的变化,都会更新这个文件。

它有什么用呢?保证当前使用的依赖包版本(源码)的一致性。如何保证呢?我们往下看。

将 composer.lock 加入版本控制

我们将 composer.lock 加入到版本控制。

通过 composer.lock 安装依赖包

运行命令:

composer install

如果存在 composer.lock 文件,Composer 会从 composer.json 中获取依赖包名称,但从 composer.lock 中获取依赖包的精确版本。最后,依然将下载的依赖包,保存到 vendor 目录。如果我们不更新依赖包,composer.lock 中的精确版本号也不会变化。当依赖包有新版本发布的时候,通过 install 安装的依然是上次更新依赖包时的版本号。这样,保证了依赖包源码的一致性。

现在,我们可以不用将 vendor 目录加到版本控制。而是通过如上的方式,来管理 vendor 目录的内容。

这样,每次依赖有更新的时候,重新执行 install 命令即可。比如,当其他人更新了依赖包信息的时候,当然也更新了 composer.lock 文件。或者,当我们在测试或生产环境,部署项目的时候。

使用依赖包

安装依赖包后,如何加载到项目中呢?我们先了解下自动加载。

每个 Composer 包都可以通过 composer.json 来说明本包需要的自动加载。比如,本例中的 Monolog,配置如下:

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

以上配置表明,按照 PSR-4 规范将命令空间 Monolog 对应到 src/Monolog 目录上。那么,比如,当需要类 Monolog\Logger 时,自动加载的 PHP 文件路径为:src/Monolog/Logger.php

现在再回来看当前项目,当安装完依赖包后,Composer 会生成一个 vendor/autoload.php 文件,此脚本已经加载了所有依赖包的自动加载配置。

我们要在项目使用依赖包的类库,直接 require 此文件即可,如下:

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

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

当然,你也可以给当前项目定义自动加载配置。比如:

"autoload": {
  "psr-4": {"App\\": "src/app/"}
}

那么,类 App\Model\User 对应的文件为 src/app/Model/User.php

每次修改了 autoload 配置,通过执行命令 dump-autoload 使其生效。

参考资料

Basic usage(getcomposer.org)(本文部分内容翻译源)

(完)


版权声明:知识共享署名-非商业性使用-禁止演绎 4.0 国际

发表评论

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