Composer 快速入门
引言
现代开发,很多的功能不需要自己从零开始实现,因为早就有人实现了这些功能,我们只需要把别人写好的代码拿过来,按照说明来使用就可以了。
相对于自家的代码,这些别人家的代码就是所谓的 依赖 或者第三方库。
显然,手动从别人那儿把代码拷贝过来是一件麻烦事儿,特别是依赖非常多的时候。而且,别人家的代码有可能进一步依赖更多人的代码,这样,你就不仅要解决自己的依赖,你还要解决依赖的依赖!毫无疑问,这其中的工作量是巨大的,人们迫切需要一个能一键解决项目依赖(包括依赖的依赖)的工具,于是,依赖管理工具应运而生。
Composer 是 PHP 的一个依赖管理工具。有了它,你可以很方便地给项目添加和删除依赖,并且在项目中引用这些依赖也变得非常简单。
下文将带你一步一步构建一个使用 Composer 来管理依赖的项目。
配置文件
新建一个文件夹,充当一个项目的根目录,然后进入。
$ mkdir demo
$ cd demo
在项目根目录下创建文件 composer.json
,这个文件用于说明项目的依赖和其他的一些元数据。
$ tree
.
└── composer.json
一个很重要的字段是 require
,对象类型,其中列出了项目所需的依赖。
{
"require": {
"monolog/monolog": "1.0.*"
}
}
如你所见,require
下的每一个键值对都意味着一个依赖。键值对包含了依赖的 包名 和对应的 版本 两部分信息:键名就是包名,键值就是要使用的版本。包名由 作者名称 和 项目名称 两部分构成,中间用一个斜杠 /
隔开。
前面的例子中,将 monolog/monolog
的版本指定为 1.0.*
版本号可以有以下几种形式:
示例 | 说明 |
---|---|
1.0.2 |
确切的版本号。 |
>=1.0 >=1.0, <2.0 <=1.0\|>=1.1 |
比较范围。逗号 , 解释为逻辑与;竖线 \| 解释为逻辑或。 |
1.0.* |
相当于 >=1.0.0, <=1.0.9 ,通配符 * 可以是 0-9 中的任一个数字。 |
1.0 - 2.0 |
相当于 >=1.0.0, <=2.0.0 |
~1.2.3 |
相当于 1.2.3 - 1.2.9 ,指定一个最小版本,允许最后一个数字增长。 |
^1.2.3 |
相当于 1.2.3 - 1.9.9 ,指定一个版本,允许向下兼容的更新。 |
安装依赖
执行 Composer 的 install
命令,配置文件中声明的依赖就会被安装,所有的包会被保存到 vendor
目录下。
$ composer install
接前面的例子,可以在 vendor/monolog/monolog/
目录中看到 monolog/monolog
的源码。
$ tree
.
├── composer.json
├── composer.lock
└── vendor
├── autoload.php
├── composer
└── monolog
└── monolog
Composer 为每个作者单独建立一个目录,在作者目录下,又为作者的每个项目单独建立一个目录。
首次执行 install
命令,Composer 还会将安装的依赖的确切版本号写入文件 composer.lock
,此后再执行 install
命令,Composer 都会优先安装 composer.lock
文件中记录的版本。
如果需要检查和更新依赖,可以使用 composer update
命令。
使用依赖
如果 Composer 只是下载、保存和更新包,那 Composer 就谈不上有很大作用。
你可能已经注意到,Composer 生成了文件 vendor/autoload.php
,你只需要简单地 include
或 require
这个文件,就可以直接使用这些包所提供的类。
创建文件 public/index.php
和日志文件 storage/logs/app.log
,现在的目录结构如下:
$ tree
.
├── composer.json
├── composer.lock
├── public
│ └── index.php
├── storage
│ └── logs
│ └── app.log
└── vendor
├── autoload.php
├── composer
└── monolog
在 public/index.php
中包含 vendor/autoload.php
,然后直接实例化 monolog/monolog
日志库的类,记录一条日志。
// public/index.php
require __DIR__ . '/../vendor/autoload.php';
$log = new Monolog\Logger('app');
$log->pushHandler(
new Monolog\Handler\StreamHandler(
__DIR__ . '/../storage/logs/app.log',
Monolog\Logger::WARNING
)
);
$log->addWarning('Foo');
运行 public/index.php
,可以看到日志已经成功写到日志文件。
$ php public/index.php
$ cat storage/logs/app.log
[2018-10-01 12:04:16] app.WARNING: Foo [] []
工作原理
Composer 是如何做到自动加载第三方类的呢?这要归功于 PHP FIG 所制定的自动加载规范 PSR-4。Composer 提供的 vendor/autoload.php
文件已经实现了这些规范,你所要做的就是了解这些规范以及在 Composer 中如何使用。
PSR-4 的核心思想就是将一个顶级命名空间与某个目录对应起来,使得该命名空间下的每一个类都能与一个确切的文件对应。比如,对于 App\Http\Kernel
类,如果将顶级命名空间 App\
映射为目录 app/
,则文件 app/Http/Kernel.php
中应该包含 App\Http\Kernel
类。
创建文件 app/Http/Kernel.php
,在这个文件中定义类 App\Http\Kernel
类。
$ tree
.
├── app
│ └── Http
│ └── Kernel.php
├── composer.json
├── composer.lock
├── public
├── storage
└── vendor
// app/Http/Kernel.php
namespace App\Http;
class Kernel
{
//
}
在文件 composer.json
中的 autoload
字段中新增字段 psr-4
,在这个字段中添加一个键值对,键值为 App\\
,键值为 app/
,这样就把将顶级命名空间 App\
映射为目录 app/
{
"require": {
"monolog/monolog": "1.0.*"
},
"autoload": {
"psr-4": {
"App\\": "app/"
}
}
}
- 命名空间名称的最后一级必须带上反斜杠
\
- 目录名后面必须带上斜杠
/
在文件 composer.json
中,反斜杆必须写两个,因为在 json 中反斜杆具有特殊含义,两个反斜杆才表示反斜杆本身。
值得注意的是,声明中的路径 app/
是相对于文件 composer.json
而言的。例如,在 monolog/monolog
日志库的 composer.json
文件中,可以找到如下自动加载器的声明。
{
"autoload": {
"psr-0": {"Monolog": "src/"}
}
}
这里的 src/
对应的是 vendor/monolog/monolog
目录下的 src
目录。
改动 autoload
字段之后,需要执行 dump-autoload
命令,让 Composer 重新生成 vendor/autoload.php
文件。
$ composer dump-autoload
Generating autoload files
此后就可以直接使用 App\Http\Kernel
类了。
// public/index.php
require __DIR__ . '/../vendor/autoload.php';
// $log = new Monolog\Logger('app');
// $log->pushHandler(
// new Monolog\Handler\StreamHandler(
// __DIR__ . '/../storage/logs/app.log',
// Monolog\Logger::WARNING
// )
// );
// $log->addWarning('Foo');
$kernel = new App\Http\Kernel();
在 autoload
字段下,除了 psr-4
字段,还可以有 psr-0
、classmap
、files
字段,它们分别对应 PSR-0、类表、文件清单自动加载方式。
开发时依赖
require
命令用于添加新的依赖。
$ composer require "summerblue/generator:~0.5" --dev
选项 --dev
表示这是一个开发时才会用到的依赖,它将出现在 composer.json
的 require-dev
字段中。
{
"require-dev": {
"summerblue/generator": "~0.5"
}
}
带 --no-dev
选项执行 install
命令,开发依赖就会被跳过。
本作品采用《CC 协议》,转载必须注明作者和本文链接
好文章,学到了 :+1: