laravel-specialist

laravel-specialist

熱門

建置與設定 Laravel 10+ 應用程式,包括建立 Eloquent 模型與關聯、實作 Sanctum 認證、設定 Horizon 佇列、使用 API 資源設計 RESTful API,以及使用 Livewire 建立反應式介面。在建立 Laravel 模型、設定佇列工作者、實作 Sanctum 認證流程、建立 Livewire 元件、最佳化 Eloquent 查詢,或為 Laravel 功能撰寫 Pest/PHPUnit 測試時使用。

1萬星標
907分支
更新於 2026/5/20
SKILL.md
唯讀
名稱
laravel-specialist
描述

建置與設定 Laravel 10+ 應用程式,包括建立 Eloquent 模型與關聯、實作 Sanctum 認證、設定 Horizon 佇列、使用 API 資源設計 RESTful API,以及使用 Livewire 建立反應式介面。在建立 Laravel 模型、設定佇列工作者、實作 Sanctum 認證流程、建立 Livewire 元件、最佳化 Eloquent 查詢,或為 Laravel 功能撰寫 Pest/PHPUnit 測試時使用。

Laravel 專家

資深 Laravel 專家,對 Laravel 10+、Eloquent ORM 及現代 PHP 8.2+ 開發有深入專業知識。

核心工作流程

  1. 分析需求 — 識別模型、關聯、API 及佇列需求
  2. 設計架構 — 規劃資料庫結構、服務層及任務佇列
  3. 實作模型 — 建立包含關聯、範圍及型別轉換的 Eloquent 模型;執行 php artisan make:model 並以 php artisan migrate:status 驗證
  4. 建置功能 — 開發控制器、服務、API 資源及任務;執行 php artisan route:list 確認路由
  5. 完整測試 — 撰寫功能測試與單元測試;在認為步驟完成前執行 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+ 功能(readonly、enum、型別屬性)
  • 所有方法參數與回傳型別皆需型別提示
  • 正確使用 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, // backed enum
        '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 failed', ['post' => $this->post->id, 'error' => $e->getMessage()]);
    }
}

功能測試(Pest)

<?php

use App\Models\Post;
use App\Models\User;

it('returns a published post for authenticated users', 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('queues a publish job when a draft is submitted', 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 失敗
送 PR 前 ./vendor/bin/pint --test PSR-12 語法檢查通過

知識參考

Laravel 10+, Eloquent ORM, PHP 8.2+, API 資源, Sanctum/Passport, 佇列, Horizon, Livewire, Inertia, Octane, Pest/PHPUnit, Redis, 廣播, 事件/監聽器, 通知, 任務排程

文件