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,你只需要简单地 includerequire 这个文件,就可以直接使用这些包所提供的类。

创建文件 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-0classmapfiles 字段,它们分别对应 PSR-0、类表、文件清单自动加载方式。

开发时依赖

require 命令用于添加新的依赖。

$ composer require "summerblue/generator:~0.5" --dev

选项 --dev 表示这是一个开发时才会用到的依赖,它将出现在 composer.jsonrequire-dev 字段中。

{
    "require-dev": {
        "summerblue/generator": "~0.5"
    }
}

--no-dev 选项执行 install 命令,开发依赖就会被跳过。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 1

好文章,学到了 :+1:

11个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!