命令行
composer dump 能跑,因为 symfony/console 允许 unambiguous prefix —— 任何 composer 子命令都可缩到能唯一匹配的最短前缀:
composer dump # = dump-autoload
composer i # = install
composer show --platform # 列本机 platform package(php / ext-* / lib-*)
--prefer-install=source|dist|auto 是 install / update 的同名 flag;--prefer-source / --prefer-dist 是它的快捷写法,三者底层同一开关。
发包瘦身
dist tarball 默认把 repo 里所有文件打进去(demo / test / CI 配置)。.gitattributes 加 export-ignore 把它们排除出 dist:
/demo export-ignore
phpunit.xml.dist export-ignore
/.github/ export-ignore
本地 git archive 预览实际 dist 包内容:
git archive HEAD --format zip -o preview.zip
几个反直觉默认
| Config | 默认 | 坑 |
|---|---|---|
process-timeout | 300s | 装大包(satis 全量索引、monorepo)容易 5 分钟撞 timeout |
platform-check | php-only | 只查 PHP 版本,不查扩展。缺扩展要等运行时 Call to undefined function 才暴露 |
discard-changes | false | source 装的包本地有改动时 update 会卡 prompt;CI 设 true 或 stash |
preferred-install | auto | 可以 per-package 配,自家 fork 走 source 方便 patch,其余走 dist |
{
"config": {
"process-timeout": 900,
"preferred-install": {
"myorg/*": "source",
"*": "dist"
}
}
}
生产环境 autoload 优化
composer install --no-dev 是基操,再加:
-o/--optimize-autoloader:把 PSR-4 规则转成 classmap,避免运行时按规则扫文件系统-a/--classmap-authoritative:autoloader 只信 classmap,不再 fallback 到文件系统 stat。隐式包含-o
-a 比 -o 更激进:classmap 没收录的类(运行期动态 include 老代码)会找不到。常规 Laravel / Symfony 应用是安全的。
运行时探查
Composer\InstalledVersions 在 Composer 2.0+ 全程可用,比读 composer.lock 干净:
use Composer\InstalledVersions;
use Composer\Semver\VersionParser;
InstalledVersions::isInstalled('vendor/package'); // bool
InstalledVersions::isInstalled('psr/log-implementation'); // virtual package(实现了 psr/log 的任意包)
InstalledVersions::isInstalled('vendor/package', false); // 仅查 require,跳过 require-dev(2.1+)
InstalledVersions::satisfies(new VersionParser, 'vendor/package', '^2.0');
InstalledVersions::getVersion('vendor/package'); // 标准化版本,如 1.2.3.0
InstalledVersions::getPrettyVersion('vendor/package'); // 原始字串,如 v1.2.3
InstalledVersions::getInstallPath('vendor/package'); // 绝对路径
InstalledVersions::getInstalledPackagesByType('foo-plugin'); // 按 composer.json 的 type 字段筛
写插件 / 探测可选依赖时 isInstalled('psr/log-implementation') 比 class_exists(LoggerInterface::class) 准 —— 后者会被 IDE / opcache stub 干扰。
composer-installed bin script 里定位资源
写在 composer.json 的 bin 字段被装到 vendor/bin/ 后,找回项目的 vendor/autoload.php 传统要 dirname(__DIR__, N) 往上猜目录,被装在不同深度就要重写。Composer 2.2+ 注入两个全局变量解决:
#!/usr/bin/env php
<?php
require $_composer_autoload_path; // 装它的项目的 vendor/autoload.php
$binDir = $_composer_bin_dir; // 装它的项目的 vendor/bin
参考
- https://getcomposer.org/doc/03-cli.md — CLI 完整 reference
- https://getcomposer.org/doc/04-schema.md — composer.json 字段
- https://getcomposer.org/doc/06-config.md — config 字段
- https://getcomposer.org/doc/07-runtime.md —
Composer\InstalledVersions