关于 solid-php
面向 Laravel 13 和 PHP 8.3+ 项目的编码技能,用于落实 SOLID 与 DRY 原则。它可识别 Laravel 或 FuseCore 模块结构,指导代码归属,并检查常见设计与可维护性问题。
主要功能
- 01识别 Laravel 和 FuseCore 结构
- 02指导模块化代码归属
- 03SOLID 重构指引
- 04检测常见反模式
- 05PHPDoc 与文件行数规则
适用场景
- 01为模块化 Laravel 项目安排新类
- 02重构过大的控制器或模型
- 03审查依赖与接口设计
- 04查找重复逻辑和缺失文档
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ fusengine/ claude-plugins --skill solid-php安装后在 Claude Code 中输入/solid-php确认已加载。
详细介绍
在 Laravel 13 + PHP 8.3+ 代码中强制遵循 SOLID 原则和 DRY:文件行数不得超过 Hook 上限 `FUSE_SOLID_MAX_LINES`,接口应拆分到 FuseCore/[Module]/App/Contracts/(共享接口则放在 FuseCore/Core/App/Contracts/),所有公共方法都必须编写 PHPDoc。自动检测 Laravel 与 FuseCore 模块化架构,并据此安排代码位置(Controllers/Requests/Actions/Services/Repositories/DTOs/Contracts/Events/Policies),同时检测反模式(臃肿类、在模型中编写业务逻辑、依赖具体实现、缺少 strict_types),并针对各项 SOLID 原则(SRP/OCP/LSP/ISP/DIP)提供重构指导。
1. 文件不得超过
SOLID PHP - Laravel 13 + PHP 8.3
Agent 工作流(强制)
任何实现开始前,必须并行启动 3 个 Agent,每个 Agent 调用一次,并各自设置一个 name:
- fuse-ai-pilot:explore-codebase - 分析现有架构
- fuse-ai-pilot:research-expert - 通过 Context7 核实 Laravel/PHP 文档
- mcp__context7__query-docs - 检查 SOLID 模式
实现完成后,运行 fuse-ai-pilot:sniper 进行验证。
DRY - 先复用,再创建(强制)
编写任何新代码之前:
- 在代码库中使用 Grep 搜索相似的类名、方法或逻辑
- 检查共享目录:
FuseCore/Core/App/Services/、FuseCore/Core/App/Traits/、FuseCore/[Module]/App/Contracts/ - 如果存在相似代码 → 扩展或复用,而不是重复实现
- 如果代码将被 2 个或更多功能使用 → 在共享 Services 或 Traits 中创建
- 将重复逻辑(出现 3 次或更多)提取到共享辅助工具或 Traits 中
- 编写完成后,确认未引入重复代码
自动检测(模块化架构为强制要求)
| 检测到的文件 | 架构 | 接口位置 |
|---|---|---|
FuseCore/ 目录 | FuseCore 模块化 | FuseCore/[Module]/App/Contracts/ |
模块中的 module.json | FuseCore 模块化 | FuseCore/[Module]/App/Contracts/ |
验证:php artisan --version → Laravel 13.x
结构:始终使用 FuseCore 模块化架构。共享内容放在 FuseCore/Core/App/。
决策树:代码应放在哪里?(FuseCore 模块化)
New code needed?
├── HTTP validation → FuseCore/[Module]/App/Http/Requests/
├── Single action → FuseCore/[Module]/App/Actions/
├── Business logic → FuseCore/[Module]/App/Services/
├── Data access → FuseCore/[Module]/App/Repositories/
├── Data transfer → FuseCore/[Module]/App/DTOs/
├── Interface → FuseCore/[Module]/App/Contracts/
├── Event → FuseCore/[Module]/App/Events/
└── Authorization → FuseCore/[Module]/App/Policies/
决策树:使用哪种模式?
| 需求 | 模式 | 位置 |
|---|---|---|
| HTTP 处理 | 控制器 | Controllers/ |
| 验证 | FormRequest | Requests/ |
| 单一操作 | Action | Actions/ |
| 复杂逻辑 | Service | Services/ |
| 数据访问 | Repository | Repositories/ |
| 数据结构 | DTO | DTOs/ |
| 抽象 | 接口 | Contracts/ |
关键规则(强制)
1. 文件不得超过 FUSE_SOLID_MAX_LINES
- 应在达到 Hook 上限之前充分拆分 - 绝不绕过限制
- 控制器:仅处理 HTTP 相关事务
- 模型:仅包含关系和类型转换
- 服务:仅包含业务逻辑
2. 分离接口(FuseCore 模块化,强制)
FuseCore/[Module]/App/Contracts/ # Module interfaces ONLY
├── UserRepositoryInterface.php
└── PaymentGatewayInterface.php
FuseCore/Core/App/Contracts/ # Shared interfaces
3. PHPDoc 为必需项
/**
* Create a new user from DTO.
*
* @param CreateUserDTO $dto User data transfer object
* @return User Created user model
* @throws ValidationException If email already exists
*/
public function create(CreateUserDTO $dto): User
参考指南
概念
| 主题 | 参考资料 | 何时查阅 |
|---|---|---|
| SOLID 概览 | solid-principles.md | 快速参考所有原则 |
| SRP | single-responsibility.md | 文件过长、控制器或模型臃肿 |
| OCP | open-closed.md | 添加支付方式、渠道 |
| LSP | liskov-substitution.md | 接口契约、切换提供程序 |
| ISP | interface-segregation.md | 接口臃肿、存在未使用的方法 |
| DIP | dependency-inversion.md | 耦合紧密、测试、模拟 |
| 反模式 | anti-patterns.md | 检测代码异味 |
| 决策 | decision-guide.md | 选择模式 |
| PHP 8.5 | php85-features.md | 现代 PHP 特性 |
| 结构 | laravel12-structure.md | 标准 Laravel |
| FuseCore | fusecore-structure.md | 模块化架构 |
模板
| 模板 | 适用场景 |
|---|---|
| code-templates.md | 服务、DTO、存储库、接口 |
| controller-templates.md | 控制器、操作、FormRequest、策略 |
| refactoring-guide.md | 从旧代码逐步迁移 |
禁止事项
| 反模式 | 检测方式 | 修复方法 |
|---|---|---|
文件超过 FUSE_SOLID_MAX_LINES | 行数 | 拆分为更小的文件 |
| 控制器包含业务逻辑 | 代码审查 | 提取到服务中 |
| 实现文件中包含接口 | 位置 | 移至 FuseCore/[Module]/App/Contracts/ |
| 模型中包含业务逻辑 | 模型中的代码 | 提取到服务中 |
| 依赖具体类 | new Class() | 通过 ModuleServiceProvider 注入 |
| 缺少 PHPDoc | 没有文档块 | 添加文档 |
| 缺少 strict_types | 没有声明 | 添加到所有文件 |
| 类臃肿 | 超过 5 个 public 方法 | 拆分职责 |
| 逻辑重复 | 同一代码出现在 2 个或更多文件中 | 提取到服务或 Trait |
| 编码前未使用 Grep | 未搜索就创建 | 先搜索代码库 |
最佳实践
| 应做 | 不应做 |
|---|---|
| 使用构造函数属性提升 | 使用属性赋值 |
| 依赖接口 | 依赖具体类 |
使用 final readonly class | 使用可变类 |
使用 declare(strict_types=1) | 跳过类型声明 |
在达到 FUSE_SOLID_MAX_LINES 之前就拆分 | 等到钩子阻止操作 |
| 使用 DTO 传输数据 | 使用数组 |
Laravel 13 注意事项
最低要求 PHP 8.3
Laravel 13 要求 PHP 8.3(L12 为 8.2)。支持 SOLID 的特性:
readonly类:final readonly class UserDto(完全不可变)- 带类型的类常量:
const int MAX_RETRIES = 3; #[\Override]属性:显式声明对父类方法的重写(可发现拼写错误)- 原生
json_validate()(比json_decode+ try/catch 更快) - 动态类常量获取:
$class::{$name}
use Override;
final readonly class PaymentService implements PaymentContract
{
public const int DEFAULT_TIMEOUT = 30;
public function __construct(
private StripeClient $stripe,
private LoggerInterface $logger,
) {}
#[Override]
public function process(PaymentDto $payment): PaymentResult
{
// ...
}
}
针对 L13 的更严格 SOLID 规则
- 所有 DTO/值对象优先使用
final readonly class - 每个继承的方法都使用
#[\Override](CI 中会检查) - 为常量指定类型(
const string ROLE = 'admin';)
评论
支持 Markdown