Composer Health Check(Composer 项目健康检查)
对 PHP Composer 项目做系统性的健康审计——先分析依赖和代码质量,列出发现的问题,经用户确认后再动手修复。
核心原则:先分析,再改动
在用户看到问题清单并明确同意之前,绝对不要改任何代码或 composer.json。 这个 skill 的目的是把问题清晰暴露出来,让用户判断哪些值得修,然后再动手。如果项目确实没什么问题,说"没什么需要优化的"是完全合理的结果——别硬找茬。
阶段一:分析诊断
按以下顺序逐项检查,每项互相独立——如果某项不适用,跳过即可。
1. 环境探测
先搞清楚项目的基本情况:
- 读取
composer.json,确定:- PHP 版本约束(
require.php)——决定哪些规范规则适用 - 项目类型——library 还是 application。有
"type": "library"的,或者没有 type 但 PSR-4 命名空间看起来是个可分发包的,就是库。库和应用有不同的规则。 - 依赖列表——直接依赖(
require)和开发依赖(require-dev) - autoload 配置——PSR-4 的 root 决定了源码在哪里
- PHP 版本约束(
- 检查有没有
composer.lock——有的话说明项目锁定了版本 - 确定源码目录(一般根据 PSR-4 映射到
src/,没有的话参考常见目录结构)
2. 依赖健康检查
运行以下诊断命令,统一加 --no-interaction --no-ansi:
A. 安全漏洞扫描
composer audit --format=json
重点关注 critical 和 high 级别的 CVE。严重程度分类详见 references/dependency-checks.md。
B. 过期依赖检查
composer outdated --direct --format=json
composer outdated --format=json # 包含间接依赖
关注:大版本落后的包(红色标记)、已废弃的包、落后多个版本的包。
C. PHP 版本升级阻塞检查
composer why-not php <当前最新稳定版>
看看有什么包阻止了 PHP 版本升级。即使暂时不升,知道有哪些阻塞也是有用的。
D. 版本约束质量
人工检查 composer.json 中的约束:
- 有没有太松的?比如
"*"、没有上界的">=7.0" - 有没有太紧的?比如精确锁定
"8.1.0"应该用"^8.1" - 开发依赖是否都放在了
require-dev里? - 对于库:约束是否特意保持宽松以避免压缩下游使用者的选择空间?(这是好事,不报问题)
3. 代码质量审查
按 PHP 最佳实践扫描源码。只能建议项目 PHP 版本支持的特性——版本对应关系:
| 特性 | 最低 PHP 版本 |
|---|---|
| 构造函数属性提升、match 表达式、命名参数、nullsafe、类型化属性、联合类型、注解 | 8.0+ |
枚举、readonly 属性、交集类型、first-class callable、never 类型 |
8.1+ |
readonly 类、DNF 类型、true/false/null 独立类型 |
8.2+ |
类型化类常量、#[\Override] |
8.3+ |
属性钩子、非对称可见性、#[\Deprecated] |
8.4+ |
按优先级依次扫描以下类别:
🔴 CRITICAL — 安全与类型
declare(strict_types=1)— 每个 PHP 文件都应该有- 缺少返回类型声明的方法
- 缺少类型声明的参数
- 缺少类型声明的属性
- 输入验证缺失
- 使用
@错误抑制符
🟡 HIGH — 现代化改造
- 可用构造函数属性提升的地方(手写
$this->prop = $param的类) - 可以用
match表达式替代的switch语句 - 可以用枚举替代的类常量组(8.1+)
- 注入/不可变属性缺少
readonly(8.1+) - 重写方法缺少
#[\Override](8.3+) - 可以简化成箭头函数的地方
🔵 MEDIUM — 结构与性能
- PSR-4 命名空间与目录对齐
- PSR-12 编码风格问题
- 上帝类 / 臃肿接口(SOLID)
- 硬编码依赖(缺少依赖注入)
- 大数据集未使用生成器
- 简单字符串操作用了正则
详见 references/code-quality-checks.md。
不要逐文件通读。 用采样的方式:
- 从关键文件入手:主要服务类、DTO/实体、控制器、命令类
- 如果某种问题反复出现,再 grep 全仓确认
- 以 PSR-4 根目录为主要扫描目标
4. 生成报告
所有检查做完后,输出结构化报告。格式如下:
# 健康检查报告:<项目名>
**PHP 版本**:<约束> (运行环境: <实际版本>)
**项目类型**:<library|application>
**扫描范围**:<N> 个 PHP 文件,目录 <源码目录>/
## 🔴 严重(立即修复)
*存在安全风险或会导致运行时错误的问题。*
| # | 类别 | 位置 | 问题描述 | 建议 |
|---|------|------|----------|------|
| 1 | 安全 | `composer audit` | `vendor/pkg` v1.2.0:CVE-2024-... | 升级到 >=1.3.0 |
## 🟡 重要(尽快修复)
*影响质量和可靠性的问题。*
| # | 类别 | 位置 | 问题描述 | 建议 |
|---|------|------|----------|------|
| ... | | | | |
## 🔵 建议(可考虑)
*让代码更健康的长期改进项。*
| # | 类别 | 位置 | 问题描述 | 建议 |
|---|------|------|----------|------|
| ... | | | | |
## ✅ 做得好的地方
*项目已经做得很好的点,值得肯定。*
- ...
## 未检查 / 跳过
*不适用或因项目类型/规模跳过的项目。*
- ...
如果 没有发现任何问题,清晰告知:
# 健康检查报告:<项目名>
✅ **没有发现任何问题。** 项目看起来很健康——依赖都是最新的,没有安全漏洞,代码符合 PHP <版本> 的最佳实践。
*已检查:安全审计、<N> 项过期检查、<N> 条代码规范、扫描了 <M> 个文件。*
优先级判定规则:
- 安全漏洞一律 🔴 严重
- 大部分文件缺 strict_types 是 🔴 严重(类型强制转换 bug 的温床)
- 大版本落后是 🟡 重要(如果同时有 CVE 则升级到 🔴 严重)
- 代码质量优化是 🔵 建议,除非影响到了可靠性
- 对库项目:不要报版本约束太宽——那是设计如此
阶段二:确认修复
报告展示完后,问用户:
"你想让我修复哪些?可以说编号(比如「修 1、3、5」)、说类别(比如「修所有严重的」)、或者说「不用修」你自己来处理。"
修复时注意:
- 一次修一个——改完说明做了什么,再改下一个
- 依赖更新:用
composer update/composer require命令,不要手改composer.json里的约束 - 代码修改:用 Edit 工具,保持和周围代码风格一致
- 全部修完:再跑一次
composer audit,确认漏洞已修复
库项目的特殊处理
你维护的大部分是 Composer 库,处理时注意:
- 不要建议收紧
require约束——库应该保持广泛兼容。需要的话用composer bump --dev-only。 composer bump(不带--dev-only)只适用于应用——它会收紧约束,对库的下游使用者造成兼容问题。- 版本约束习惯:
"^8.1"对库是好的(允许 8.1-8.x)。">=8.1"没有上界会让将来的大版本迁移更困难。 - autoload 优化:检查 PSR-4 映射是否和命名空间根目录一致。
.gitattributes:建议把 tests、docs、CI 配置标记为 export-ignore(减小包下载体积)。
快速扫描
用户只想快速看一下时,跳过深度代码审查,只做:
composer audit --format=jsoncomposer outdated --direct --format=json- 抽查 3-5 个代表性源文件,检查 strict_types、返回类型、现代特性
- 简短报告,只列 🔴 严重和 🟡 重要