本文目录导读:

梳理并精简PHP项目的依赖,通常分为两个大方向:自动检测(利用工具)和 手动分析(理解业务与框架)。
下面是一套比较完整的梳理与精简方案,分为分析现状、精简操作、持续管控三个阶段。
第一阶段:全面分析与诊断
在删除任何依赖之前,必须知道哪些是真正用到的,哪些是“幽灵依赖”。
使用 Composer 自带分析工具
# 1. 查看为什么某个包被安装(依赖树分析) composer why package/name # 2. 反向查看某个包被哪些项目依赖 composer why-not package/name # 3. 生成完整的依赖关系图(文本版) composer depends --tree package/name # 4. 检查是否存在可更新的版本(兼容当前约束) composer outdated --direct # 只看直接依赖 composer outdated --major # 看大版本升级
静态代码分析工具(推荐)
这是最精准的方法,扫描代码中实际被 use 或 require 的包。
工具推荐: maglnet/composer-require-checker
# 安装 composer require --dev maglnet/composer-require-checker # 运行分析 ./vendor/bin/composer-require-checker check
它会输出:
- Missing packages:代码中用了但
composer.json没声明(这是问题) - Unused packages:
composer.json声明了但代码中没直接调用(这是可精简目标)
注意: 该工具只能检测直接依赖,间接依赖(A依赖B,B依赖C)如果C在代码中显式被 use,也会被标记为未声明。
检查 require-dev / require 分类
很多包不应该出现在生产环境的 require 中。
| 包类型 | 应归属 | 理由 |
|---|---|---|
| PHPUnit, PHPStan, PHPCS | require-dev |
仅开发/CI用 |
| Faker, Mockery | require-dev |
仅测试用 |
| Laravel Debugbar, Telescope | require-dev |
仅开发环境 |
| Laravel Horizon, Redis 驱动 | require |
生产环境需要 |
| 代码生成器(如 ide-helper) | require-dev |
仅开发时运行 |
快速检查命令:
# 查看哪些 dev 包被错误放入 require composer show --self
分析框架自带的功能
许多框架已经内置了常见功能,无需额外包。
- Laravel:自带 Guzzle,无需额外装 HTTP 客户端;自带验证规则,不需要额外验证库;自带邮箱发送,不需要
swiftmailer(新版 laravel 已经内置 symfony mailer) - Symfony:大量 Bundle 可能包含不需要的子依赖
- ThinkPHP / Yii:检查是否有更精简的替代实现
第二阶段:执行精简操作
移除未使用的直接依赖
根据分析结果,对每个疑似无用包:
# 先模拟移除 composer remove package/name --dry-run # 确认无误后实际移除 composer remove package/name # 清理整个 vendor 和锁文件 rm -rf vendor composer.lock composer install
替代臃肿的包(常见案例)
| 臃肿包 | 替代方案 | 节省空间 |
|---|---|---|
guzzlehttp/guzzle |
symfony/http-client 或 php-curl-class |
减少 2-3 个间接路由包 |
monolog/monolog |
直接使用 Psr\Log\LoggerInterface + error_log() |
如果业务简单,可省掉整个 monolog 体系 |
doctrine/dbal |
PDO + 原生 SQL | 对于非复杂查询,可精简几十个依赖 |
laravel/framework |
拆分为 illuminate/* 单独组 |
只取需要的组件 |
intervention/image |
spatie/image 或直接 GD/Imagick |
体积更小,依赖更少 |
spatie/laravel-permission |
自己写 2 个关系表 + 中间件 | 省掉一个完整权限包的 10+ 依赖 |
合并功能相似的包
- ✅
league/flysystem+league/flysystem-aws-s3-v3可以合并配置 - ✅ 多个
spatie/*包如果只用了其中一小部分功能,考虑手动实现 - ❌ 不要同时装
guzzlehttp/guzzle+symfony/http-client+php-curl处理同一类事情
移除 composer.json 中的无用约束
{
"require": {
"php": ">=7.4 || >=8.0" // 可以压缩为 ">=7.4"
}
}
第三阶段:持续管控与监控
建立 CI 检查流水线
在 .github/workflows/ci.yml 或 .gitlab-ci.yml 中添加:
- name: 检查未使用的依赖
run: |
composer require --dev maglnet/composer-require-checker
vendor/bin/composer-require-checker check
定期运行依赖审计
# 检查已知安全漏洞 composer audit # 检查是否有更新的替代包 composer suggest --all
锁定版本策略
避免使用 ^1.0 这种宽松约束导致意外引入新包:
{
"require": {
"vendor/package": "1.2.*" // 只允许小版本更新
}
}
使用 prefer-lowest 做兼容性测试
composer update --prefer-lowest
这能帮你发现哪些包实际上限制了更旧但可以工作的版本。
典型案例:Laravel 项目依赖精简
假设一个标准的 Laravel 8/9/10 项目,composer.json 往往有 20~30 个包,精简后可能降到 10~15 个。
可移除项:
| 包名 | 移除理由 |
|---|---|
facade/ignition |
Laravel 10+ 已用 flare 替代,早期版本可直接删 |
nunomaduro/collision |
终端输出美化,不影响运行 |
laravel/sail |
Docker 环境,不需要在生产 require 中 |
barryvdh/laravel-ide-helper |
仅开发环境 |
laravel/tinker |
如果不在生产环境 php artisan tinker,可移入 dev |
laravel/sanctum |
如果不用 API token 认证,可移除 |
laravel/horizon |
如果不用 Redis 队列管理,可移除 |
最终精简后示例:
{
"require": {
"php": "^8.1",
"laravel/framework": "^10.0"
// 仅保留业务必须的业务包
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"nunomaduro/collision": "^7.0",
"spatie/laravel-ignition": "^1.0"
}
}
最后建议
- 不要追求极致精简:省掉一个包往往意味着自己维护代码,带来的维护成本可能更高
- 优先移除
require-dev中的误放包:这直接影响生产环境 docker 镜像体积 - 利用
composer why反向溯源:当你发现一个看似无用的包时,先查它被谁依赖 - 保留 composer.lock:精简后重新生成锁文件,确保环境一致性
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播