使用 Composer

尽管 Composer 并不是实现 MVC 模式的必要组件,但在过去几年中,它已成为任何 PHP 网络应用程序不可或缺的工具。该工具的主要目标是帮助您管理应用程序的依赖关系,即我们需要在应用程序中使用的第三方库(代码)。我们只需创建一个列出这些库的配置文件,并在命令行中运行一条命令,就能实现这一目标。

您需要在开发机器上安装 Composer(参见第 1 章,设置环境)。请执行以下命令确保已安装:

$ composer –version

这应该返回您的 Composer 安装版本。如果没有,请返回安装部分来解决问题。

管理依赖

如前所述,Composer 的主要目标是管理依赖关系。例如,我们已经实现了我们的配置读取器 Config 类,但如果我们知道有人实现了更好的版本,我们可以直接使用他们的版本,而不是重新发明轮子;只要确保他们允许你这样做!

开源

开放源代码指的是开发人员编写并与社区共享的代码,以便他人无限制地使用。许可证实际上有多种类型,有些许可证比其他许可证更灵活,但基本理念是我们可以在自己的应用程序中重复使用其他开发人员编写的库。这有助于社区知识的增长,因为我们可以学习他人所做的工作,加以改进,然后分享。

我们已经实现了一个不错的配置读取器,但应用程序中还有其他元素需要完成。让我们利用 Composer 重用别人的库。有几种方法可以为我们的项目添加依赖关系:在命令行中执行命令,或者手动编辑配置文件。由于我们还没有 Composer 的配置文件,所以使用第一种方法。在应用程序的根目录下执行以下命令:

$ composer require monolog/monolog

该命令将显示以下结果:

Using version ^1.17 for monolog/monolog
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing psr/log (1.0.0)
  Downloading: 100%

- Installing monolog/monolog (1.17.2)
  Downloading: 100%
...
Writing lock file
Generating autoload files

通过这条命令,我们要求 Composer 将 monolog/monolog 库添加为应用程序的依赖关系。执行该命令后,我们现在可以看到目录中的一些变化:

  • 我们有一个名为 composer.json 的新文件。这是配置文件,我们可以在其中添加依赖项。

  • 我们有一个名为 composer.lock 的新文件。这是 Composer 用来跟踪已安装的依赖项及其版本的文件。

  • 我们有一个名为 vendor 的新目录。该目录包含 Composer 下载的依赖项的代码。

命令的输出还显示了一些额外信息。在本例中,它显示下载了两个库或软件包,尽管我们只要求下载一个。原因是我们需要的软件包还包含其他依赖项,而这些依赖项已被 Composer 解决。还请注意 Composer 下载的版本;由于我们没有指定任何版本,Composer 使用了最新的版本,但您可以尝试编写所需的特定版本。

我们还需要另一个库,这里是 twig/twig。让我们用以下命令将其添加到依赖列表中:

$ composer require twig/twig

该命令将显示以下结果:

Using version ^1.23 for twig/twig
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing twig/twig (v1.23.1)
  Downloading: 100%

Writing lock file
Generating autoload files

如果我们检查 composer.json 文件,我们将看到以下内容:

{
    "require": {
        "monolog/monolog": "^1.17",
        "twig/twig": "^1.23"
    }
}

该文件只是一个 JSON 映射,其中包含应用程序的配置;在本例中,是我们安装的两个依赖项的列表。正如你所看到的,依赖库的名称遵循一种模式:用斜线分隔的两个单词。第一个单词指的是开发该库的供应商。第二个词是库本身的名称。依赖库有一个版本,它可以是准确的版本号—​在本例中就是这样—​也可以包含通配符或标记名。有关这方面的更多信息,请访问 https://getcomposer.org/doc/articles/alias.md

最后,如果你想添加另一个依赖项,或者以其他方式编辑 composer.json 文件,你应该在命令行中运行 composer update,或者不管 composer.json 文件在哪里,以便更新依赖项。

使用 PSR-4 自动加载器

在前面几章中,我们还为应用程序添加了自动加载器。由于我们现在使用的是别人的代码,因此也需要知道如何加载他们的类。很快,开发人员意识到,如果没有标准,这种情况几乎无法管理,于是他们提出了一些标准,大多数开发人员都会遵循。有关这方面的大量信息,请访问 http://www.php-fig.org

现在,PHP 有两种主要的自动加载标准:PSR-0PSR-4。它们非常相似,但我们将采用后者,因为它是最新发布的标准。该标准基本上沿用了我们在讨论命名空间时已经介绍过的内容:类的命名空间必须与它所在的目录相同,类的名称应该是文件名,后跟扩展名 .php。例如,src/Domain/Book.php 中的文件包含名称空间 Bookstore\Domain 中的类 Book

使用 Composer 的应用程序应遵循其中一种标准,并在各自的 composer.json 文件中注明所使用的标准。这意味着 Composer 知道如何自动加载自己的应用程序文件,所以我们在下载外部库时就不需要再处理这个问题了。为此,我们可以编辑 composer.json 文件,并添加以下内容:

{
    "require": {
        "monolog/monolog": "^1.17",
        "twig/twig": "^1.23"
    },
    "autoload": {
        "psr-4": {
            "Bookstore\\": "src"
        }
    }
}

前面的代码表示,我们将在应用程序中使用 PSR-4,所有以 Bookstore 开头的命名空间都应在 src/ 目录中找到。这正是我们的自动加载器已经在做的事情,只不过是在配置文件中减少了几行而已。现在我们可以放心地删除自动加载器和对它的任何引用了。

Composer 会生成一些映射,帮助加快类的加载速度。为了根据添加到配置文件中的新信息更新这些映射,我们需要运行之前运行的 composer update 命令。这一次,输出结果将告诉我们没有软件包需要更新,但自动加载文件将再次生成:

$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Writing lock file
Generating autoload files

添加元数据

为了知道在哪里可以找到您定义为依赖库的库,Composer 会保存一个软件包和版本库,即 Packagist。该资源库为开发人员保存了大量有用信息,如特定软件包的所有可用版本、作者、软件包功能的一些描述(或指向该信息的网站),以及该软件包将下载的依赖库。您还可以浏览软件包,按名称或类别进行搜索。

但 Packagist 是如何知道这些信息的呢?这要归功于 composer.json 文件本身。在该文件中,您可以用 Composer 可以理解的格式定义应用程序的所有元数据。让我们来看一个例子。在 composer.json 文件中添加以下内容:

{
    "name": "picahielos/bookstore",
    "description": "Manages an online bookstore.",
    "minimum-stability": "stable",
    "license": "Apache-2.0",
    "type": "project",
    "authors": [
        {
            "name": "Antonio Lopez",
            "email": "antonio.lopez.zapata@gmail.com"
        }
    ],
    // ...
}

现在,配置文件按照 Composer 惯例包含了软件包的名称:供应商名称、斜线和软件包名称(本例中为 picahielos/bookstore)。我们还添加了描述、许可证、作者和其他元数据。如果您将代码放在 GitHub 等公共仓库中,添加此 composer.json 文件后,您就可以访问 Packagist 并插入仓库的 URL。Packagist 会从您的 composer.json 文件中提取信息,将您的代码添加为一个新包。它会根据你的标签或分支显示可用的版本。要了解更多信息,请访问 https://getcomposer.org/doc/04-schema.md 上的官方文档。

index.php 文件

在 MVC 应用程序中,我们通常使用一个文件来获取所有请求,并根据 URL 将它们路由到特定的控制器。这种逻辑通常可以在根目录下的 index.php 文件中找到。我们已经有了一个,但由于我们正在根据 MVC 模式调整我们的功能,我们将不再需要当前的 index.php。因此,你可以放心地用下面的文件替换它:

<?php
require_once __DIR__ . '/vendor/autoload.php';

该文件现在要做的唯一一件事就是包含处理 Composer 代码中所有自动加载的文件。稍后,我们将在这里初始化所有内容,如数据库连接、配置读取器等,但现在,让它保持为空。