mcpField
L
laravel-best-practices

laravel-best-practices

github.com/asyrafhussin开发952.3k 次安装9 周前更新
代码仓库

关于 laravel-best-practices

面向 Laravel 13 应用开发者的实践指南,涵盖架构、Eloquent、控制器、验证和安全,并在规则文件中提供示例。

主要功能

  1. 01架构与结构指南
  2. 02Eloquent 和数据库实践
  3. 03控制器与路由模式
  4. 04验证与请求规则
  5. 05批量赋值安全指南

适用场景

  1. 01规划 Laravel 应用结构
  2. 02减少 N+1 数据库查询
  3. 03实现表单请求验证
  4. 04防范模型批量赋值风险

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/asyrafhussin/agent-skills --skill laravel-best-practices

安装后在 Claude Code 中输入/laravel-best-practices确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

AGENTS.md
metadata.json
README.md
rules/
_sections.md
_template.md
arch-action-classes.md
arch-dto-pattern.md
arch-event-driven.md
arch-feature-folders.md
arch-queue-routing.md
arch-repository-pattern.md
arch-service-classes.md
arch-value-objects.md
controller-api-resources.md
controller-dependency-injection.md
controller-form-requests.md
controller-middleware.md
controller-resource-controllers.md
controller-resource-methods.md
controller-single-action.md
eloquent-accessors-mutators.md
eloquent-casts.md
eloquent-chunking.md
eloquent-eager-loading.md
eloquent-model-events.md
eloquent-pruning.md
eloquent-query-scopes.md
eloquent-relationships.md
eloquent-soft-deletes.md
eloquent-vector-search.md

详细介绍

Laravel 13 最佳实践

Laravel 13 应用的全面最佳实践指南。包含 7 个类别中的 31 条规则,助你构建可扩展、易维护的 Laravel 应用。

适用场景

在以下场景中参考这些指南:

  • 创建控制器、模型和服务
  • 编写迁移和数据库查询
  • 实施验证和表单请求
  • 使用 Laravel 构建 API
  • 规划 Laravel 应用结构

按优先级排列的规则类别

优先级类别影响前缀
1架构与结构严重arch-
2Eloquent 与数据库严重eloquent-
3控制器与路由高controller-、ctrl-
4验证与请求高validation-、valid-
5安全高sec-
6性能中perf-
7API 设计中api-

快速参考

1. 架构与结构(严重)
  • arch-service-classes - 将业务逻辑提取到服务中
  • arch-action-classes - 单一用途的操作类
  • arch-repository-pattern - 何时使用仓储
  • arch-dto-pattern - 数据传输对象
  • arch-value-objects - 封装领域概念
  • arch-event-driven - 使用事件和监听器实现解耦
  • arch-feature-folders - 按领域/功能组织
  • arch-queue-routing - 集中式作业队列路由(Laravel 13+)
2. Eloquent 与数据库(严重)
  • eloquent-eager-loading - 防止 N+1 查询
  • eloquent-chunking - 处理大型数据集
  • eloquent-query-scopes - 可复用的查询逻辑
  • eloquent-model-events - 使用观察者处理副作用
  • eloquent-relationships - 正确地定义关系
  • eloquent-casts - 自动转换属性类型
  • eloquent-accessors-mutators - 转换属性
  • eloquent-soft-deletes - 安全删除并支持恢复
  • eloquent-pruning - 自动清理旧记录
  • eloquent-vector-search - 使用 pgvector 进行语义搜索(Laravel 13+)
3. 控制器与路由(高)
  • controller-resource-controllers - 使用资源控制器
  • controller-single-action - 单操作可调用控制器
  • controller-resource-methods - RESTful 资源方法
  • controller-form-requests - 使用表单请求
  • controller-api-resources - 转换 API 响应
  • controller-middleware - 正确应用中间件
  • controller-dependency-injection - 注入依赖项
4. 验证与请求(高)
  • validation-form-requests - 使用表单请求类
  • validation-custom-rules - 创建自定义规则
  • validation-conditional-rules - 条件验证
  • validation-array-validation - 验证嵌套数组
  • validation-after-hooks - 复杂验证逻辑
5. 安全(高)
  • sec-mass-assignment - 防止批量赋值
6. 性能(中)

此类别目前尚无规则文件。

7. API 设计(中)

此类别目前尚无规则文件。

基本模式

带表单请求的控制器
<?php

namespace App\Http\Controllers;

use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use App\Models\Post;
use Illuminate\Http\RedirectResponse;

class PostController extends Controller
{
    public function store(StorePostRequest $request): RedirectResponse
    {
        // Validation happens automatically
        $validated = $request->validated();

        $post = Post::create($validated);

        return redirect()
            ->route('posts.show', $post)
            ->with('success', 'Post created successfully.');
    }

    public function update(UpdatePostRequest $request, Post $post): RedirectResponse
    {
        $post->update($request->validated());

        return redirect()
            ->route('posts.show', $post)
            ->with('success', 'Post updated successfully.');
    }
}
表单请求类
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StorePostRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', Post::class);
    }

    public function rules(): array
    {
        return [
            'title' => ['required', 'string', 'max:255'],
            'body' => ['required', 'string', 'min:100'],
            'category_id' => ['required', 'exists:categories,id'],
            'tags' => ['nullable', 'array'],
            'tags.*' => ['exists:tags,id'],
            'published_at' => ['nullable', 'date', 'after:now'],
        ];
    }

    public function messages(): array
    {
        return [
            'body.min' => 'The post body must be at least 100 characters.',
        ];
    }
}
服务类模式
<?php

namespace App\Services;

use App\Models\User;
use App\Models\Post;
use App\Events\PostPublished;
use Illuminate\Support\Facades\DB;

class PostService
{
    public function __construct(
        private readonly NotificationService $notifications,
    ) {}

    public function publish(Post $post): Post
    {
        return DB::transaction(function () use ($post) {
            $post->update([
                'published_at' => now(),
                'status' => 'published',
            ]);

            event(new PostPublished($post));

            $this->notifications->notifyFollowers($post->author, $post);

            return $post->fresh();
        });
    }
}
Eloquent 模型
<?php

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\BelongsToMany;
use Illuminate\Database\Eloquent\Builder;

class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'title',
        'slug',
        'body',
        'category_id',
        'published_at',
    ];

    protected $casts = [
        'published_at' => 'datetime',
    ];

    // Relationships
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }

    public function tags(): BelongsToMany
    {
        return $this->belongsToMany(Tag::class)->withTimestamps();
    }

    // Scopes
    public function scopePublished(Builder $query): Builder
    {
        return $query->whereNotNull('published_at')
            ->where('published_at', '<=', now());
    }

    public function scopeByCategory(Builder $query, int $categoryId): Builder
    {
        return $query->where('category_id', $categoryId);
    }

    // Accessors & Mutators
    protected function title(): Attribute
    {
        return Attribute::make(
            set: fn (string $value) => ucfirst($value),
        );
    }
}
迁移最佳实践
<?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) {
            $table->id();
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            $table->foreignId('category_id')->constrained()->cascadeOnDelete();
            $table->string('title');
            $table->string('slug')->unique();
            $table->text('body');
            $table->timestamp('published_at')->nullable();
            $table->timestamps();

            // Indexes for common queries
            $table->index(['user_id', 'published_at']);
            $table->index('category_id');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('posts');
    }
};
预加载
// N+1 Problem
$posts = Post::all();
foreach ($posts as $post) {
    echo $post->author->name;  // Query per post
}

// Eager loading — only 3 queries total
$posts = Post::with(['author', 'category', 'tags'])->get();
foreach ($posts as $post) {
    echo $post->author->name;  // No additional queries
}

// Nested eager loading
$posts = Post::with([
    'author.profile',
    'comments.user',
    'tags',
])->get();

// Constrained eager loading
$posts = Post::with([
    'comments' => fn ($query) => $query->latest()->limit(5),
])->get();

使用方法

阅读各条规则文件,了解详细说明和代码示例:

rules/arch-service-classes.md
rules/eloquent-eager-loading.md
rules/validation-form-requests.md
rules/_sections.md

每个规则文件都包含:

  • 带元数据(标题、影响、标签)的 YAML frontmatter
  • 简要说明该规则的重要性
  • 错误示例及说明
  • 正确示例及说明
  • Laravel 13 和 PHP 8.3 的特定背景与参考资料

完整汇编文档

查看包含所有规则完整内容的指南:AGENTS.md

评论

支持 Markdown