Back to list
changgenglu

laravel-expert

by changgenglu

0🍴 0📅 Jan 23, 2026

SKILL.md


name: "laravel-expert" description: "Activates when user requests Laravel framework guidance, version migration, Eloquent patterns, middleware design, service container usage, or Laravel best practices. Do NOT use for generic PHP questions unrelated to the framework. Examples: 'How to use Service Container?', 'Translate this to Laravel 12'."

Laravel Expert Skill

🧠 Expertise

Laravel 框架專家,專精於跨版本開發、框架核心機制與最佳實務。

官方文檔參考https://laravel.com/docs/


1. 版本差異對照表

1.1 支援政策

版本PHP 版本發布日期Bug 修復結束安全修復結束
9.x8.0 - 8.22022-022023-082024-02
10.x8.1 - 8.32023-022024-082025-02
11.x8.2 - 8.42024-032025-092026-03
12.x8.2+2025-022026-082027-02

參考https://laravel.com/docs/12.x/releases#support-policy

1.2 核心差異對照

特性Laravel 9Laravel 11Laravel 12
目錄結構傳統完整精簡化精簡化
app/Http/Kernel.php✅ 存在❌ 移除❌ 移除
Middleware 註冊Kernelbootstrap/app.phpbootstrap/app.php
Exception Handlerapp/Exceptionsbootstrap/app.phpbootstrap/app.php
預設測試框架PHPUnitPest 可選Pest 預設
Model Casts$casts 屬性casts() 方法casts() 方法
前端工具MixViteVite
Starter KitsBreeze/JetstreamBreeze/Jetstream新 Starter Kits

1.3 Laravel 9 主要特性

// 新版 Accessor / Mutator 語法
use Illuminate\Database\Eloquent\Casts\Attribute;

protected function name(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value),
        set: fn (string $value) => strtolower($value),
    );
}

// Enum Casting
protected $casts = [
    'status' => OrderStatus::class,
];

// Controller Route Groups
Route::controller(OrderController::class)->group(function () {
    Route::get('/orders', 'index');
    Route::post('/orders', 'store');
});

1.4 Laravel 11/12 精簡化結構

// bootstrap/app.php(Laravel 11+)
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->web(append: [
            CheckUserStatus::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->render(function (NotFoundHttpException $e) {
            return response()->json(['error' => 'Not found'], 404);
        });
    })
    ->create();

2. Service Container 與依賴注入

2.1 基本綁定

// 綁定介面到實作
$this->app->bind(IPaymentGateway::class, StripeGateway::class);

// 單例綁定
$this->app->singleton(IPaymentGateway::class, StripeGateway::class);

// 實例綁定
$this->app->instance(IPaymentGateway::class, $gateway);

// 上下文綁定
$this->app->when(OrderService::class)
    ->needs(IPaymentGateway::class)
    ->give(StripeGateway::class);

2.2 自動解析

// 自動注入(Constructor Injection)
class OrderController extends Controller
{
    public function __construct(
        private readonly IOrderService $orderService,
        private readonly IPaymentGateway $paymentGateway,
    ) {}
}

// 方法注入
public function store(Request $request, IOrderService $service)
{
    $order = $service->createOrder($request->validated());
}

3. Middleware 設計

3.1 Laravel 9 方式(Kernel)

// app/Http/Kernel.php
protected $middlewareGroups = [
    'web' => [
        // ...
    ],
    'api' => [
        \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

protected $middlewareAliases = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];

3.2 Laravel 11+ 方式(bootstrap/app.php)

->withMiddleware(function (Middleware $middleware) {
    // 新增到 web 群組
    $middleware->web(append: [
        CheckUserStatus::class,
    ]);
    
    // 新增到 api 群組
    $middleware->api(prepend: [
        EnsureTokenIsValid::class,
    ]);
    
    // 別名
    $middleware->alias([
        'admin' => EnsureUserIsAdmin::class,
    ]);
    
    // 全域 Middleware
    $middleware->append(LogRequests::class);
})

3.3 自訂 Middleware

class EnsureUserIsActive
{
    public function handle(Request $request, Closure $next): Response
    {
        if ($request->user()?->status !== 'active') {
            abort(403, 'Your account is not active.');
        }
        
        return $next($request);
    }
}

4. Eloquent 進階模式

4.1 Query Scope

// Local Scope
public function scopeActive(Builder $query): void
{
    $query->where('status', 'active');
}

public function scopeOfType(Builder $query, string $type): void
{
    $query->where('type', $type);
}

// 使用
User::active()->ofType('admin')->get();

// Global Scope(自動套用)
class ActiveScope implements Scope
{
    public function apply(Builder $builder, Model $model): void
    {
        $builder->where('deleted_at', null);
    }
}

4.2 Accessor & Mutator

// Laravel 9+ 新語法
use Illuminate\Database\Eloquent\Casts\Attribute;

protected function fullName(): Attribute
{
    return Attribute::make(
        get: fn () => "{$this->first_name} {$this->last_name}",
    );
}

protected function password(): Attribute
{
    return Attribute::make(
        set: fn (string $value) => Hash::make($value),
    );
}

4.3 Custom Casts

class MoneyCast implements CastsAttributes
{
    public function get(Model $model, string $key, mixed $value, array $attributes): Money
    {
        return new Money($value, $attributes['currency'] ?? 'USD');
    }
    
    public function set(Model $model, string $key, mixed $value, array $attributes): int
    {
        return $value instanceof Money ? $value->cents : $value;
    }
}

// 使用
protected function casts(): array
{
    return [
        'price' => MoneyCast::class,
    ];
}

5. Event / Listener / Observer

5.1 Event 與 Listener

// 定義 Event
class OrderPlaced
{
    public function __construct(
        public readonly Order $order,
    ) {}
}

// 定義 Listener
class SendOrderConfirmation
{
    public function handle(OrderPlaced $event): void
    {
        Mail::to($event->order->user)->send(
            new OrderConfirmationMail($event->order)
        );
    }
}

// 觸發
event(new OrderPlaced($order));
// 或
OrderPlaced::dispatch($order);

5.2 Observer

class UserObserver
{
    public function created(User $user): void
    {
        Log::info("User created: {$user->id}");
    }
    
    public function updated(User $user): void
    {
        if ($user->isDirty('email')) {
            $user->email_verified_at = null;
        }
    }
    
    public function deleted(User $user): void
    {
        $user->orders()->delete();
    }
}

// 註冊(AppServiceProvider)
User::observe(UserObserver::class);

6. Form Request 驗證

6.1 基本用法

class StoreOrderRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('create', Order::class);
    }
    
    public function rules(): array
    {
        return [
            'product_id' => ['required', 'exists:products,id'],
            'quantity' => ['required', 'integer', 'min:1', 'max:100'],
            'notes' => ['nullable', 'string', 'max:500'],
        ];
    }
    
    public function messages(): array
    {
        return [
            'product_id.exists' => '商品不存在',
            'quantity.min' => '數量至少為 1',
        ];
    }
}

6.2 進階驗證

public function rules(): array
{
    return [
        'email' => [
            'required',
            'email',
            Rule::unique('users')->ignore($this->user),
        ],
        'role' => [
            'required',
            Rule::in(['admin', 'user', 'guest']),
        ],
        'status' => [
            'required',
            Rule::enum(UserStatus::class),
        ],
    ];
}

// 條件驗證
public function withValidator(Validator $validator): void
{
    $validator->sometimes('phone', 'required', function ($input) {
        return $input->contact_method === 'phone';
    });
}

7. Policy / Gate 權限

7.1 Policy 定義

class OrderPolicy
{
    public function view(User $user, Order $order): bool
    {
        return $user->id === $order->user_id;
    }
    
    public function update(User $user, Order $order): bool
    {
        return $user->id === $order->user_id 
            && $order->status === 'pending';
    }
    
    public function delete(User $user, Order $order): bool
    {
        return $user->isAdmin();
    }
}

// 使用
$this->authorize('update', $order);
// 或
Gate::authorize('update', $order);
// 或
if ($user->can('update', $order)) { }

7.2 Gate 定義

// AuthServiceProvider 或 AppServiceProvider
Gate::define('access-admin', function (User $user) {
    return $user->role === 'admin';
});

Gate::define('edit-settings', function (User $user) {
    return $user->isAdmin();
});

// 使用
if (Gate::allows('access-admin')) { }
@can('access-admin') ... @endcan

8. 升級遷移指南

8.1 Laravel 9 → 10

變更項目處理方式
PHP 8.1 最低版本升級 PHP
PHPUnit 10更新測試配置
Pest 2更新 Pest

8.2 Laravel 10 → 11

變更項目處理方式
目錄結構精簡化可選擇保留或遷移
Kernel.php 移除遷移到 bootstrap/app.php
Exception Handler 移除遷移到 bootstrap/app.php
Model casts() 方法可選擇遷移

8.3 Laravel 11 → 12

預計升級時間:5 分鐘(官方建議) 參考https://laravel.com/docs/12.x/upgrade

影響程度項目
更新依賴 (laravel/framework ^12.0)
Model UUIDv7 變更
Carbon 3、Image 驗證排除 SVG
# 升級命令
composer require laravel/framework:^12.0 phpunit/phpunit:^11.0 pestphp/pest:^3.0

9. 常用 Artisan 命令

# 開發
php artisan serve
php artisan tinker
php artisan route:list

# 快取
php artisan optimize
php artisan optimize:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache

# 資料庫
php artisan migrate
php artisan migrate:fresh --seed
php artisan db:seed

# 產生器
php artisan make:model Order -mfsc  # Model + Migration + Factory + Seeder + Controller
php artisan make:request StoreOrderRequest
php artisan make:policy OrderPolicy --model=Order
php artisan make:event OrderPlaced
php artisan make:listener SendOrderNotification --event=OrderPlaced

10. Laravel 檢查清單

版本相容

  • PHP 版本是否符合要求?
  • 依賴套件是否支援目標 Laravel 版本?
  • 是否有廢棄 API 使用?

架構設計

  • 是否使用 Service 層處理業務邏輯?
  • 是否使用 Repository 模式?
  • 是否正確使用依賴注入?
  • 是否為高風險操作設定 Policy?

效能

  • 是否使用 Eager Loading?
  • 是否設定適當快取?
  • 是否使用 Queue 處理耗時任務?

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon