💻 Développement

dev-laravel-guide

Développement PHP Laravel avec Eloquent ORM, Blade templates, migrations, middleware, queues et Sanctum.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- dev-laravel-guide --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } dev-laravel-guide -Launch"

🚀 Déjà installé ?

claude "/dev-laravel-guide"

Ou tapez /dev-laravel-guide dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

LaravelEloquentBladeartisanmigration LaravelPHP Laravel

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/dev-laravel-guide ~/.claude/skills/

Payload du plugin : skills/dev-laravel-guide · source éditable : dev-skills/laravel-guide

📖 Manuel

Guide Laravel

1. Choisir l'architecture cible

BesoinArchitecture recommandée
API REST mobile/SPALaravel + Sanctum, routes/api.php, resources JSON
Full-stack SSRMVC classique + Blade + Livewire
Back-office réactifInertia.js + Vue/React via Breeze/Jetstream
Monolithe modulaireDDD : app/Modules/{Domain}/ avec Services + Repositories

Commande de départ selon le preset :

composer create-project laravel/laravel mon-app   # blank
composer create-project laravel/breeze            # auth + Blade/Inertia
php artisan install:api                           # ajoute routes/api.php + Sanctum (Laravel 11+)

2. Structure du projet

app/
  Http/
    Controllers/      # thin controllers — pas de logique métier
    Requests/         # validation ici UNIQUEMENT
    Resources/        # transformation JSON (API)
    Middleware/
  Models/             # Eloquent — relations, casts, scopes
  Services/           # logique métier testable
  Actions/            # une classe = une opération (Action pattern)
  Repositories/       # abstraction BDD si DDD
  Jobs/               # tâches async
  Policies/           # autorisation

3. Models Eloquent

// Génération
php artisan make:model Product -mfsc   # model + migration + factory + seeder + controller

// Relations
public function orders(): HasMany
{
    return $this->hasMany(Order::class);
}

// Cast + Accessor (Laravel 9+)
protected $casts = ['price' => 'decimal:2', 'meta' => 'array'];

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

// Scope local réutilisable
public function scopeActive(Builder $query): Builder
{
    return $query->where('status', 'active');
}
// usage : Product::active()->paginate(20);

Eager loading — obligatoire :

// MAUVAIS — N+1
foreach (Order::all() as $order) { echo $order->user->name; }

// BON
Order::with('user', 'items.product')->paginate(50);

// Détecter en dev
Model::preventLazyLoading(! app()->isProduction());  // dans AppServiceProvider

4. Controllers et routes

// Controller ressource
php artisan make:controller ProductController --resource --model=Product

// routes/api.php
Route::middleware('auth:sanctum')->group(function () {
    Route::apiResource('products', ProductController::class);
    Route::post('products/{product}/publish', [ProductController::class, 'publish']);
});

// Controller thin
public function store(StoreProductRequest $request): JsonResponse
{
    $product = $this->productService->create($request->validated());
    return new ProductResource($product);
}

API Resources pour contrôler la sérialisation :

php artisan make:resource ProductResource
// Dans la resource :
return ['id' => $this->id, 'price' => $this->price_formatted];

5. Validation avec Form Requests

php artisan make:request StoreProductRequest
public function rules(): array
{
    return [
        'name'     => ['required', 'string', 'max:255'],
        'price'    => ['required', 'numeric', 'min:0'],
        'category' => ['required', Rule::in(Category::pluck('slug'))],
    ];
}
// authorize() retourne true si gate/policy gérée ailleurs

Jamais de $request->validate() dans le controller si la logique est réutilisable.

6. Migrations et base de données

// Création
php artisan make:migration create_products_table

// Schema Builder
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->foreignId('category_id')->constrained()->cascadeOnDelete();
    $table->string('name');
    $table->decimal('price', 10, 2);
    $table->json('meta')->nullable();
    $table->timestamps();
    $table->index(['category_id', 'price']); // index composite
});

// Commandes courantes
php artisan migrate:fresh --seed     # reset dev
php artisan migrate --step           # une migration à la fois
php artisan migrate:rollback --step=2

7. Authentification et autorisation

# Sanctum (API tokens + SPA)
php artisan install:api
# Passport (OAuth2 complet)
php artisan passport:install
// Policy
php artisan make:policy ProductPolicy --model=Product

public function update(User $user, Product $product): bool
{
    return $user->id === $product->user_id || $user->hasRole('admin');
}

// Dans le controller
$this->authorize('update', $product);

Gates pour les actions non liées à un model :

Gate::define('access-dashboard', fn (User $u) => $u->is_admin);

8. Queues et Jobs

php artisan make:job SendWelcomeEmail
php artisan queue:work redis --tries=3 --backoff=60
php artisan queue:failed          # voir les jobs échoués
php artisan queue:retry all
// Dispatch
SendWelcomeEmail::dispatch($user)->onQueue('emails')->delay(now()->addMinutes(2));

// Dans le Job
public function handle(): void { /* pas d'injection lourde ici */ }
public function failed(Throwable $e): void { /* log, alerter */ }

Scheduler (Laravel 11 : routes/console.php) :

Schedule::job(GenerateReportsJob::class)->dailyAt('02:00')->withoutOverlapping();

9. Tests

php artisan make:test ProductTest          # PHPUnit feature test
php artisan make:test ProductUnitTest --unit
php artisan test --filter ProductTest --parallel
// Feature test API
public function test_user_can_create_product(): void
{
    $user = User::factory()->create();
    $response = $this->actingAs($user, 'sanctum')
        ->postJson('/api/products', ['name' => 'Widget', 'price' => 9.99]);

    $response->assertCreated()->assertJsonPath('data.name', 'Widget');
    $this->assertDatabaseHas('products', ['name' => 'Widget', 'user_id' => $user->id]);
}

// Mock d'un service
$this->mock(PaymentGateway::class, fn ($mock) =>
    $mock->shouldReceive('charge')->once()->andReturn(true)
);

10. Optimisation et déploiement

# Cache tout pour la prod
php artisan optimize        # config + routes + views
php artisan icons:cache     # si Blade Icons
php artisan event:cache

# Rollback rapide
php artisan optimize:clear

# Horizon (Redis queues dashboard)
composer require laravel/horizon && php artisan horizon:install

Variables .env critiques en prod :

APP_ENV=production
APP_DEBUG=false
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=redis
LOG_CHANNEL=stack

Anti-patterns et garde-fous

Anti-patternSolution
Logique métier dans le controllerExtraire dans un Service ou Action
User::all() sans limitToujours paginer : ->paginate(20)
Relations lazy loadées en boucleModel::with(...) ou preventLazyLoading()
dd() oublié en prodray() en dev uniquement, Log:: en prod
Migrations irréversibles sans down()Toujours implémenter down()
Secrets dans le code.env + config/services.php, jamais en dur
$fillable = ['*'] ou $guarded = []Lister explicitement les champs fillable
Jobs sans timeoutDéfinir public $timeout = 60; et $tries = 3
Test sans RefreshDatabaseUtiliser le trait pour isolation

Références rapides

php artisan route:list --path=api      # lister routes API
php artisan tinker                     # REPL Eloquent
php artisan model:show Product         # inspect model
php artisan db:monitor                 # surveiller les connexions
php artisan about                      # infos environnement