PHP项目项目依赖如何梳理精简

wen PHP项目 21

本文目录导读:

PHP项目项目依赖如何梳理精简

  1. 第一阶段:全面分析与诊断
  2. 第二阶段:执行精简操作
  3. 第三阶段:持续管控与监控
  4. 典型案例:Laravel 项目依赖精简
  5. 最后建议

梳理并精简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    # 看大版本升级

静态代码分析工具(推荐)

这是最精准的方法,扫描代码中实际被 userequire 的包。

工具推荐: maglnet/composer-require-checker

# 安装
composer require --dev maglnet/composer-require-checker
# 运行分析
./vendor/bin/composer-require-checker check

它会输出:

  • Missing packages:代码中用了但 composer.json 没声明(这是问题)
  • Unused packagescomposer.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-clientphp-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"
  }
}

最后建议

  1. 不要追求极致精简:省掉一个包往往意味着自己维护代码,带来的维护成本可能更高
  2. 优先移除 require-dev 中的误放包:这直接影响生产环境 docker 镜像体积
  3. 利用 composer why 反向溯源:当你发现一个看似无用的包时,先查它被谁依赖
  4. 保留 composer.lock:精简后重新生成锁文件,确保环境一致性

抱歉,评论功能暂时关闭!