Composer 是 PHP 的包管理器。在项目文件夹中运行 composer require vendor/package:Composer 会把库下载到 vendor/,记录到 composer.json 中,然后你只需一行 require __DIR__ . '/vendor/autoload.php';,就能加载它以及其他所有已安装的包。
composer require monolog/monolog
<?php
require __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
$log = new Logger('app');
$log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Level::Warning));
$log->warning('Disk almost full', ['free' => '2%']);
不需要为每个文件写 include:自动加载器会在第一次需要某个类时,加载 Logger、StreamHandler 以及它们用到的所有类。包来自 Packagist,这是 Composer 默认搜索的公共仓库。
安装 Composer
Composer 需要你的电脑上先装好 PHP(参见安装 PHP)。
Windows:从 getcomposer.org 下载并运行 Composer-Setup.exe。它会找到你的 php.exe,并把 composer 添加到 PATH。安装完成后打开一个新的终端。
macOS 使用 Homebrew:
brew install composer
Linux:发行版自带的包(Debian 和 Ubuntu 上是 sudo apt install composer)可以用,但版本往往比较旧。官方安装程序提供的是最新版本:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
getcomposer.org 的下载页面还提供了一行在运行安装程序前校验其哈希值的命令;请从那里复制命令,以获得最新的哈希值。然后检查它能否正常工作:
composer --version
composer.json 和 composer.lock
composer init 会问几个问题,然后写出 composer.json;或者在你第一次 composer require 一个包时自动创建它。一个典型的例子:
{
"name": "acme/shop",
"require": {
"php": ">=8.2",
"monolog/monolog": "^3.0",
"vlucas/phpdotenv": "^5.6"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
require列出项目运行所需的依赖,包括 PHP 版本。require-dev列出只在开发时使用的工具(测试、静态分析)。composer require --dev phpunit/phpunit会往这里添加,composer install --no-dev会在生产服务器上跳过它们。autoload告诉 Composer 你自己的类放在哪里(见下文)。
Composer 还会在旁边写出 composer.lock,记录它安装的每个包的确切版本,包括你的包所依赖的包。两个文件都要提交。不要提交 vendor/:把它加入 .gitignore,因为 composer install 会根据 lock 文件重新生成它。
composer install 与 composer update
composer install # install exactly what composer.lock says
composer update # pick the newest allowed versions, rewrite composer.lock
composer update monolog/monolog # update one package only
composer remove monolog/monolog # uninstall and remove from composer.json
composer outdated # list packages with newer versions available
克隆项目后以及每次部署时运行 composer install:每个人都会拿到经过测试的相同版本。只有在打算升级时才运行 composer update,然后测试并提交新的 composer.lock。在生产服务器上运行 update 会安装没有人测试过的版本。
版本约束:^ 和 ~
| 约束 | 允许的版本 | 适用场景 |
|---|---|---|
^3.2 | 3.2.0 到 4.0.0(不含) | 常规选择:获得新功能和修复,不会出现破坏性的主版本 |
^0.4 | 0.4.0 到 0.5.0(不含) | 1.0 之前的包,次版本也可能有破坏性变更 |
~3.2 | 3.2.0 到 4.0.0(不含) | 和 ^3.2 相同 |
~3.2.1 | 3.2.1 到 3.3.0(不含) | 只要修复 |
3.2.1 | 只允许 3.2.1 | 很少使用,它会挡住安全修复 |
>=3.2 <3.5 | 自定义范围 | 绕开某个有问题的版本 |
composer require vendor/package 不写版本时,会选择最新的稳定版本,并为它写入一个 ^ 约束,这通常正是你想要的。
用 PSR-4 自动加载自己的类
PSR-4 是一种把命名空间映射到文件夹的约定:配置 "App\\": "src/" 后,类 App\Text\Slug 就位于 src/Text/Slug.php。添加 autoload 部分后,运行:
composer dump-autoload
Composer 的自动加载器是一个用 spl_autoload_register() 注册的函数,每当代码用到一个尚未加载的类时,PHP 就会调用它。下面的代码块会写出两个类文件,并注册一个自己的小型 PSR-4 自动加载器,让你亲眼看到映射是怎么工作的。试着再添加第三个类文件并使用它。
自动加载器对每个类只运行一次:第二次调用 Slug::from() 时没有输出 autoload: 行,因为这个类已经加载过了。在真实项目中,你永远不需要自己写这个函数;vendor/autoload.php 会注册 Composer 的版本,它还会处理 vendor/ 中的包。命名空间的内容见命名空间页面。
常见错误
Class "Monolog\Logger" not found。脚本没有require 'vendor/autoload.php',或者路径写错了。使用__DIR__ . '/vendor/autoload.php',这样路径就不会依赖当前目录。- 自己的类加入
autoload后仍然找不到。运行composer dump-autoload,并检查文件路径是否与命名空间完全一致,包括大小写:App\Text\Slug必须对应src/Text/Slug.php,Linux 服务器会把src/text/slug.php当成另一个文件。 Your requirements could not be resolved to an installable set of packages。两个包需要某个依赖(通常是 PHP 本身)的互不兼容的版本。错误信息会列出冲突;composer why-not vendor/package 2.0可以解释是什么挡住了某个版本。- 系统提示无法识别
composer。终端是在安装之前打开的,或者安装文件夹不在 PATH 中。打开一个新的终端,或者直接调用php composer.phar。
常见问题
composer install 和 composer update 有什么区别?
composer install 安装的正是 composer.lock 中记录的版本,所以每台机器拿到的代码都一样;克隆项目后和部署时运行它。composer update 会解析 composer.json 允许的最新版本,安装它们并重写 composer.lock;只有在你打算升级时才运行它。
composer.lock 和 vendor 文件夹需要提交吗?
对于应用程序,要提交 composer.lock,这样每个人安装的版本都相同。不要提交 vendor/:把它加入 .gitignore,让 composer install 重新生成它。
composer.json 中的 ^ 是什么意思?
^2.3 允许从 2.3.0 到 3.0.0(不含)之间的任何版本:可以获得新功能和修复,但不会升级到可能破坏代码的新主版本。~2.3 的含义相同,而 ~2.3.1 只允许 2.3.1 起的 2.3.x 版本。
怎么用 Composer 自动加载自己的类?
在 composer.json 中添加 "autoload": {"psr-4": {"App\\": "src/"}},运行 composer dump-autoload,然后 require 'vendor/autoload.php'。之后第一次使用类 App\Mail\Mailer 时,它会从 src/Mail/Mailer.php 加载。
怎么查看安装的 Composer 版本?
运行 composer --version。要升级 Composer 本身,运行 composer self-update,或者通过当初安装它的包管理器升级,例如 brew upgrade composer。