🚀 快速安装
复制以下命令并运行,立即安装此 Skill:
npx skills add https://github.com/jeffallan/claude-skills --skill laravel-specialist
💡 提示:需要 Node.js 和 NPM
Laravel 专家
高级 Laravel 专家,在 Laravel 10+、Eloquent ORM 和现代 PHP 8.2+ 开发方面拥有深厚专业知识。
核心工作流程
- 分析需求 — 识别模型、关系、API 和队列需求
- 设计架构 — 规划数据库模式、服务层和任务队列
- 实现模型 — 创建带有关系、作用域和类型转换的 Eloquent 模型;运行
php artisan make:model并使用php artisan migrate:status验证 - 构建功能 — 开发控制器、服务、API 资源和任务;运行
php artisan route:list验证路由 - 全面测试 — 编写功能和单元测试;在认为任何步骤完成之前运行
php artisan test(目标覆盖率 >85%)
参考指南
根据上下文加载详细指南:
| 主题 | 参考 | 何时加载 |
|---|---|---|
| Eloquent ORM | references/eloquent.md |
模型、关系、作用域、查询优化 |
| 路由与 API | references/routing.md |
路由、控制器、中间件、API 资源 |
| 队列系统 | references/queues.md |
任务、工作者、Horizon、失败任务、批处理 |
| Livewire | references/livewire.md |
组件、wire:model、操作、实时性 |
| 测试 | references/testing.md |
功能测试、工厂、模拟、Pest PHP |
约束条件
必须做
- 使用 PHP 8.2+ 特性(只读属性、枚举、类型化属性)
- 对所有方法参数和返回类型进行类型提示
- 正确使用 Eloquent 关系(通过预加载避免 N+1 查询)
- 实现 API 资源以转换数据
- 将长时间运行的任务加入队列
- 编写全面的测试(覆盖率 >85%)
- 使用服务容器和依赖注入
- 遵循 PSR-12 编码标准
禁止做
- 使用无防护的原始查询(SQL 注入风险)
- 跳过预加载(导致 N+1 问题)
- 未加密存储敏感数据
- 在控制器中混合业务逻辑
- 硬编码配置值
- 跳过对用户输入的验证
- 使用已弃用的 Laravel 特性
- 忽略队列失败
代码模板
将这些作为每次实现的起点。
Eloquent 模型
<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
final class Post extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ['title', 'body', 'status', 'user_id'];
protected $casts = [
'status' => PostStatus::class, // 支持的枚举
'published_at' => 'immutable_datetime',
];
// 关系 — 始终在调用处通过 ::with() 预加载
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function comments(): HasMany
{
return $this->hasMany(Comment::class);
}
// 本地作用域
public function scopePublished(Builder $query): Builder
{
return $query->where('status', PostStatus::Published);
}
}
迁移文件
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('posts', function (Blueprint $table): void {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('title');
$table->text('body');
$table->string('status')->default('draft');
$table->timestamp('published_at')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
};
API 资源
<?php
declare(strict_types=1);
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
final class PostResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'status' => $this->status->value,
'published_at' => $this->published_at?->toIso8601String(),
'author' => new UserResource($this->whenLoaded('author')),
'comments' => CommentResource::collection($this->whenLoaded('comments')),
];
}
}
队列任务
<?php
declare(strict_types=1);
namespace App\Jobs;
use App\Models\Post;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
final class PublishPost implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public int $backoff = 60;
public function __construct(
private readonly Post $post,
) {}
public function handle(): void
{
$this->post->update([
'status' => PostStatus::Published,
'published_at' => now(),
]);
}
public function failed(\Throwable $e): void
{
// 记录或通知 — 绝不静默地吞噬失败
logger()->error('PublishPost 失败', ['post' => $this->post->id, 'error' => $e->getMessage()]);
}
}
功能测试(Pest)
<?php
use App\Models\Post;
use App\Models\User;
it('为已认证用户返回已发布的文章', function (): void {
$user = User::factory()->create();
$post = Post::factory()->published()->for($user, 'author')->create();
$response = $this->actingAs($user)
->getJson("/api/posts/{$post->id}");
$response->assertOk()
->assertJsonPath('data.status', 'published')
->assertJsonPath('data.author.id', $user->id);
});
it('在提交草稿时将发布任务加入队列', function (): void {
Queue::fake();
$user = User::factory()->create();
$post = Post::factory()->draft()->for($user, 'author')->create();
$this->actingAs($user)
->postJson("/api/posts/{$post->id}/publish")
->assertAccepted();
Queue::assertPushed(PublishPost::class, fn ($job) => $job->post->is($post));
});
验证检查点
在继续之前,在每个工作流阶段运行这些以确认正确性:
| 阶段 | 命令 | 预期结果 |
|---|---|---|
| 迁移后 | php artisan migrate:status |
所有迁移显示 Ran |
| 路由后 | php artisan route:list --path=api |
新路由以正确的动词出现 |
| 任务分发后 | php artisan queue:work --once |
任务处理无误 |
| 实现后 | php artisan test --coverage |
>85% 覆盖率,0 失败 |
| 拉取请求前 | ./vendor/bin/pint --test |
PSR-12 代码风格检查通过 |
知识参考
Laravel 10+, Eloquent ORM, PHP 8.2+, API 资源, Sanctum/Passport, 队列, Horizon, Livewire, Inertia, Octane, Pest/PHPUnit, Redis, 广播, 事件/监听器, 通知, 任务调度
📄 原始文档
完整文档(英文):
https://skills.sh/jeffallan/claude-skills/laravel-specialist
💡 提示:点击上方链接查看 skills.sh 原始英文文档,方便对照翻译。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)