Laravel 11 : Créer une application complète de A à Z
Guide complet pour créer une application Laravel 11 avec authentification, API REST, Eloquent ORM et déploiement. Tutorial pratique pour débutants et intermédiaires.

Laravel 11 redéfinit le développement PHP moderne avec une architecture simplifiée et des performances optimisées. Cette version majeure supprime de nombreux fichiers de configuration par défaut, introduit une structure allégée et améliore significativement l'expérience développeur. Ce guide accompagne la création d'une application complète de gestion de tâches, de l'installation au déploiement.
Laravel 11 adopte une structure minimaliste : plus de fichiers Kernel, configuration consolidée dans bootstrap/app.php, et un dossier app/ épuré. Le framework requiert PHP 8.2 minimum et intègre nativement SQLite pour un démarrage rapide.
Installation et configuration du projet
Laravel 11 s'installe via Composer ou l'installateur Laravel. La nouvelle structure du projet est plus légère, avec moins de fichiers de configuration à gérer dès le départ.
# terminal
# Installation de l'installateur Laravel (recommandé)
composer global require laravel/installer
# Création d'un nouveau projet Laravel 11
laravel new task-manager
# Ou directement avec Composer
composer create-project laravel/laravel task-manager
# Navigation vers le projet
cd task-managerL'installateur propose plusieurs options interactives : choix du starter kit (Breeze, Jetstream), du système de test (Pest, PHPUnit) et de la base de données.
# terminal
# Lancement du serveur de développement
php artisan serve
# Le serveur démarre sur http://localhost:8000Configuration de la base de données
Laravel 11 utilise SQLite par défaut, idéal pour le développement. Pour une application de production, la configuration vers MySQL ou PostgreSQL se fait dans le fichier .env.
# .env
# Configuration pour MySQL
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=task_manager
DB_USERNAME=root
DB_PASSWORD=secret
# Configuration pour PostgreSQL (alternative)
# DB_CONNECTION=pgsql
# DB_HOST=127.0.0.1
# DB_PORT=5432
# DB_DATABASE=task_manager
# DB_USERNAME=postgres
# DB_PASSWORD=secretLa connexion à la base de données se vérifie avec une commande Artisan.
# terminal
# Vérification de la connexion à la base de données
php artisan db:show
# Exécution des migrations par défaut
php artisan migrateCréation du modèle et des migrations
Eloquent ORM simplifie la manipulation des données avec des modèles expressifs. La commande make:model génère le modèle, la migration, le contrôleur et la factory en une seule fois.
# terminal
# Génération du modèle Task avec migration, factory, seeder et contrôleur
php artisan make:model Task -mfsc
# -m : migration
# -f : factory
# -s : seeder
# -c : controllerCette commande crée quatre fichiers essentiels pour une gestion complète des tâches.
<?php
// database/migrations/2026_01_14_000000_create_tasks_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration pour créer la table des tâches
return new class extends Migration
{
public function up(): void
{
Schema::create('tasks', function (Blueprint $table) {
// Clé primaire auto-incrémentée
$table->id();
// Relation avec l'utilisateur propriétaire
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
// Titre de la tâche (obligatoire)
$table->string('title');
// Description détaillée (optionnelle)
$table->text('description')->nullable();
// Statut : pending, in_progress, completed
$table->string('status')->default('pending');
// Priorité : low, medium, high
$table->string('priority')->default('medium');
// Date d'échéance (optionnelle)
$table->date('due_date')->nullable();
// Marqueur de complétion
$table->timestamp('completed_at')->nullable();
// Timestamps automatiques (created_at, updated_at)
$table->timestamps();
// Soft deletes pour la corbeille
$table->softDeletes();
// Index pour optimiser les requêtes fréquentes
$table->index(['user_id', 'status']);
$table->index('due_date');
});
}
public function down(): void
{
Schema::dropIfExists('tasks');
}
};La migration définit la structure de la table avec des relations, des index et le soft delete pour ne jamais perdre de données accidentellement.
<?php
// app/Models/Task.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\SoftDeletes;
use Illuminate\Database\Eloquent\Builder;
class Task extends Model
{
// Traits pour les fonctionnalités avancées
use HasFactory, SoftDeletes;
// Attributs mass-assignables
protected $fillable = [
'user_id',
'title',
'description',
'status',
'priority',
'due_date',
'completed_at',
];
// Casting automatique des attributs
protected function casts(): array
{
return [
'due_date' => 'date',
'completed_at' => 'datetime',
];
}
// Constantes pour les statuts valides
public const STATUS_PENDING = 'pending';
public const STATUS_IN_PROGRESS = 'in_progress';
public const STATUS_COMPLETED = 'completed';
// Constantes pour les priorités
public const PRIORITY_LOW = 'low';
public const PRIORITY_MEDIUM = 'medium';
public const PRIORITY_HIGH = 'high';
// Relation : une tâche appartient à un utilisateur
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
// Scope : tâches en attente
public function scopePending(Builder $query): Builder
{
return $query->where('status', self::STATUS_PENDING);
}
// Scope : tâches en cours
public function scopeInProgress(Builder $query): Builder
{
return $query->where('status', self::STATUS_IN_PROGRESS);
}
// Scope : tâches terminées
public function scopeCompleted(Builder $query): Builder
{
return $query->where('status', self::STATUS_COMPLETED);
}
// Scope : tâches en retard
public function scopeOverdue(Builder $query): Builder
{
return $query->where('due_date', '<', now())
->whereNull('completed_at');
}
// Scope : tâches d'un utilisateur
public function scopeForUser(Builder $query, int $userId): Builder
{
return $query->where('user_id', $userId);
}
// Accesseur : vérifie si la tâche est en retard
public function getIsOverdueAttribute(): bool
{
return $this->due_date
&& $this->due_date->isPast()
&& !$this->completed_at;
}
// Méthode : marquer comme terminée
public function markAsCompleted(): void
{
$this->update([
'status' => self::STATUS_COMPLETED,
'completed_at' => now(),
]);
}
}Le modèle Task utilise les scopes Eloquent pour des requêtes lisibles et réutilisables. Les constantes centralisent les valeurs valides pour les statuts et priorités.
Le trait SoftDeletes ajoute une colonne deleted_at. Les tâches supprimées ne disparaissent pas de la base de données mais sont marquées comme supprimées. Utilisez withTrashed() pour les inclure dans les requêtes.
Configuration de l'authentification avec Breeze
Laravel Breeze fournit une authentification complète avec des vues Blade ou une API. L'installation prend quelques minutes et génère tout le nécessaire : routes, contrôleurs, vues et tests.
# terminal
# Installation de Laravel Breeze
composer require laravel/breeze --dev
# Installation du stack Blade (traditionnel)
php artisan breeze:install blade
# Ou pour une API uniquement (SPA/mobile)
php artisan breeze:install api
# Compilation des assets
npm install && npm run build
# Exécution des migrations (tables users, sessions, etc.)
php artisan migrateBreeze génère les routes d'authentification, les contrôleurs et les vues pour inscription, connexion, réinitialisation de mot de passe et vérification d'email.
<?php
// app/Models/User.php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
protected function casts(): array
{
return [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}
// Relation : un utilisateur possède plusieurs tâches
public function tasks(): HasMany
{
return $this->hasMany(Task::class);
}
// Raccourci : tâches en attente de l'utilisateur
public function pendingTasks(): HasMany
{
return $this->tasks()->pending();
}
// Raccourci : tâches en retard de l'utilisateur
public function overdueTasks(): HasMany
{
return $this->tasks()->overdue();
}
}Prêt à réussir tes entretiens Laravel ?
Entraîne-toi avec nos simulateurs interactifs, fiches express et tests techniques.
Création du contrôleur et des routes
Le contrôleur orchestre la logique métier entre les requêtes HTTP et le modèle. Laravel 11 encourage les contrôleurs à action unique ou les ressources RESTful.
<?php
// app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use Illuminate\Support\Facades\Gate;
class TaskController extends Controller
{
// Liste des tâches de l'utilisateur connecté
public function index(Request $request): View
{
// Récupération des tâches avec filtrage optionnel
$tasks = $request->user()
->tasks()
->when($request->status, fn($q, $status) => $q->where('status', $status))
->when($request->priority, fn($q, $priority) => $q->where('priority', $priority))
->orderBy('due_date')
->orderBy('priority', 'desc')
->paginate(15);
return view('tasks.index', compact('tasks'));
}
// Formulaire de création
public function create(): View
{
return view('tasks.create');
}
// Enregistrement d'une nouvelle tâche
public function store(Request $request): RedirectResponse
{
// Validation des données entrantes
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date|after_or_equal:today',
]);
// Création de la tâche liée à l'utilisateur
$request->user()->tasks()->create($validated);
return redirect()
->route('tasks.index')
->with('success', 'Tâche créée avec succès.');
}
// Affichage d'une tâche
public function show(Task $task): View
{
// Vérification que l'utilisateur est propriétaire
Gate::authorize('view', $task);
return view('tasks.show', compact('task'));
}
// Formulaire d'édition
public function edit(Task $task): View
{
Gate::authorize('update', $task);
return view('tasks.edit', compact('task'));
}
// Mise à jour d'une tâche
public function update(Request $request, Task $task): RedirectResponse
{
Gate::authorize('update', $task);
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'status' => 'required|in:pending,in_progress,completed',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date',
]);
// Mise à jour de completed_at si statut = completed
if ($validated['status'] === Task::STATUS_COMPLETED && !$task->completed_at) {
$validated['completed_at'] = now();
}
$task->update($validated);
return redirect()
->route('tasks.index')
->with('success', 'Tâche mise à jour.');
}
// Suppression d'une tâche
public function destroy(Task $task): RedirectResponse
{
Gate::authorize('delete', $task);
$task->delete();
return redirect()
->route('tasks.index')
->with('success', 'Tâche supprimée.');
}
// Marquer comme terminée (action rapide)
public function complete(Task $task): RedirectResponse
{
Gate::authorize('update', $task);
$task->markAsCompleted();
return back()->with('success', 'Tâche terminée !');
}
}Le contrôleur utilise les Gates pour l'autorisation, la validation intégrée et le route model binding pour un code concis et sécurisé.
Définition des routes
Les routes définissent les URLs et les associent aux actions du contrôleur. Laravel 11 centralise les routes dans routes/web.php.
<?php
// routes/web.php
use App\Http\Controllers\TaskController;
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
// Page d'accueil publique
Route::get('/', function () {
return view('welcome');
});
// Routes protégées par authentification
Route::middleware(['auth', 'verified'])->group(function () {
// Dashboard avec statistiques
Route::get('/dashboard', function () {
$user = auth()->user();
return view('dashboard', [
'totalTasks' => $user->tasks()->count(),
'pendingTasks' => $user->tasks()->pending()->count(),
'completedTasks' => $user->tasks()->completed()->count(),
'overdueTasks' => $user->tasks()->overdue()->count(),
]);
})->name('dashboard');
// Routes RESTful pour les tâches
Route::resource('tasks', TaskController::class);
// Action rapide pour compléter une tâche
Route::patch('/tasks/{task}/complete', [TaskController::class, 'complete'])
->name('tasks.complete');
// Routes du profil (générées par Breeze)
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
// Routes d'authentification (générées par Breeze)
require __DIR__.'/auth.php';La méthode Route::resource() génère automatiquement les sept routes RESTful standard : index, create, store, show, edit, update et destroy.
Mise en place des policies d'autorisation
Les policies centralisent la logique d'autorisation pour chaque modèle. Elles déterminent qui peut effectuer quelles actions sur les ressources.
# terminal
# Génération de la policy pour Task
php artisan make:policy TaskPolicy --model=Task<?php
// app/Policies/TaskPolicy.php
namespace App\Policies;
use App\Models\Task;
use App\Models\User;
class TaskPolicy
{
// Vérification avant toutes les méthodes
// Retourner true bypass toutes les vérifications (admin)
public function before(User $user, string $ability): ?bool
{
if ($user->is_admin) {
return true;
}
return null; // Continue vers les méthodes spécifiques
}
// Peut voir la liste des tâches
public function viewAny(User $user): bool
{
return true; // Tout utilisateur authentifié
}
// Peut voir une tâche spécifique
public function view(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Peut créer une tâche
public function create(User $user): bool
{
return true;
}
// Peut modifier une tâche
public function update(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Peut supprimer une tâche
public function delete(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Peut restaurer une tâche supprimée (soft delete)
public function restore(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
// Peut supprimer définitivement
public function forceDelete(User $user, Task $task): bool
{
return $user->id === $task->user_id;
}
}Laravel découvre automatiquement les policies grâce aux conventions de nommage. La policy TaskPolicy s'applique au modèle Task.
Les policies sont essentielles pour la sécurité. Sans elles, un utilisateur pourrait manipuler les URLs pour accéder aux tâches d'autres utilisateurs. Toujours vérifier la propriété des ressources.
Création d'une API REST
Laravel facilite la création d'APIs RESTful avec des routes dédiées, des ressources JSON et Sanctum pour l'authentification.
# terminal
# Installation de Sanctum (inclus par défaut depuis Laravel 11)
php artisan install:api
# Cette commande :
# - Publie les migrations Sanctum
# - Ajoute le trait HasApiTokens au modèle User
# - Configure les routes API<?php
// app/Http/Controllers/Api/TaskController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\TaskResource;
use App\Http\Resources\TaskCollection;
use App\Models\Task;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
class TaskController extends Controller
{
// Liste paginée des tâches
public function index(Request $request): AnonymousResourceCollection
{
$tasks = $request->user()
->tasks()
->when($request->status, fn($q, $s) => $q->where('status', $s))
->when($request->priority, fn($q, $p) => $q->where('priority', $p))
->when($request->boolean('overdue'), fn($q) => $q->overdue())
->latest()
->paginate($request->input('per_page', 15));
return TaskResource::collection($tasks);
}
// Création d'une tâche
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:5000',
'priority' => 'required|in:low,medium,high',
'due_date' => 'nullable|date|after_or_equal:today',
]);
$task = $request->user()->tasks()->create($validated);
return response()->json([
'message' => 'Task created successfully.',
'data' => new TaskResource($task),
], 201);
}
// Affichage d'une tâche
public function show(Task $task): TaskResource
{
$this->authorize('view', $task);
return new TaskResource($task);
}
// Mise à jour d'une tâche
public function update(Request $request, Task $task): TaskResource
{
$this->authorize('update', $task);
$validated = $request->validate([
'title' => 'sometimes|required|string|max:255',
'description' => 'nullable|string|max:5000',
'status' => 'sometimes|required|in:pending,in_progress,completed',
'priority' => 'sometimes|required|in:low,medium,high',
'due_date' => 'nullable|date',
]);
if (isset($validated['status'])
&& $validated['status'] === Task::STATUS_COMPLETED
&& !$task->completed_at) {
$validated['completed_at'] = now();
}
$task->update($validated);
return new TaskResource($task->fresh());
}
// Suppression d'une tâche
public function destroy(Task $task): JsonResponse
{
$this->authorize('delete', $task);
$task->delete();
return response()->json([
'message' => 'Task deleted successfully.',
]);
}
}Ressources API pour la transformation des données
Les ressources API transforment les modèles Eloquent en réponses JSON structurées, contrôlant précisément les données exposées.
<?php
// app/Http/Resources/TaskResource.php
namespace App\Http\Resources;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;
class TaskResource extends JsonResource
{
public function toArray(Request $request): array
{
return [
'id' => $this->id,
'title' => $this->title,
'description' => $this->description,
'status' => $this->status,
'priority' => $this->priority,
'due_date' => $this->due_date?->format('Y-m-d'),
'is_overdue' => $this->is_overdue,
'completed_at' => $this->completed_at?->toISOString(),
'created_at' => $this->created_at->toISOString(),
'updated_at' => $this->updated_at->toISOString(),
// Inclusion conditionnelle de l'utilisateur
'user' => $this->whenLoaded('user', fn() => [
'id' => $this->user->id,
'name' => $this->user->name,
]),
];
}
}Routes API avec authentification Sanctum
<?php
// routes/api.php
use App\Http\Controllers\Api\TaskController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
// Route pour récupérer l'utilisateur authentifié
Route::get('/user', function (Request $request) {
return $request->user();
})->middleware('auth:sanctum');
// Routes API protégées par Sanctum
Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('tasks', TaskController::class);
// Statistiques du tableau de bord
Route::get('/dashboard/stats', function (Request $request) {
$user = $request->user();
return response()->json([
'total' => $user->tasks()->count(),
'pending' => $user->tasks()->pending()->count(),
'in_progress' => $user->tasks()->inProgress()->count(),
'completed' => $user->tasks()->completed()->count(),
'overdue' => $user->tasks()->overdue()->count(),
]);
});
});Tests automatisés avec Pest
Laravel 11 intègre Pest PHP par défaut, un framework de test élégant et expressif. Les tests garantissent que l'application fonctionne correctement après chaque modification.
<?php
// tests/Feature/TaskTest.php
use App\Models\Task;
use App\Models\User;
// Test : un utilisateur peut voir ses tâches
test('user can view their tasks', function () {
$user = User::factory()->create();
$tasks = Task::factory()->count(5)->for($user)->create();
$response = $this->actingAs($user)->get('/tasks');
$response->assertOk();
$response->assertViewHas('tasks');
});
// Test : un utilisateur peut créer une tâche
test('user can create a task', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)->post('/tasks', [
'title' => 'Nouvelle tâche',
'description' => 'Description de la tâche',
'priority' => 'high',
'due_date' => now()->addDays(7)->format('Y-m-d'),
]);
$response->assertRedirect('/tasks');
$this->assertDatabaseHas('tasks', [
'user_id' => $user->id,
'title' => 'Nouvelle tâche',
'priority' => 'high',
]);
});
// Test : validation requise pour le titre
test('task title is required', function () {
$user = User::factory()->create();
$response = $this->actingAs($user)->post('/tasks', [
'title' => '',
'priority' => 'medium',
]);
$response->assertSessionHasErrors('title');
});
// Test : un utilisateur ne peut pas voir les tâches d'un autre
test('user cannot view another users task', function () {
$user = User::factory()->create();
$otherUser = User::factory()->create();
$task = Task::factory()->for($otherUser)->create();
$response = $this->actingAs($user)->get("/tasks/{$task->id}");
$response->assertForbidden();
});
// Test : marquer une tâche comme terminée
test('user can complete a task', function () {
$user = User::factory()->create();
$task = Task::factory()->for($user)->create(['status' => 'pending']);
$response = $this->actingAs($user)->patch("/tasks/{$task->id}/complete");
$response->assertRedirect();
$task->refresh();
expect($task->status)->toBe('completed');
expect($task->completed_at)->not->toBeNull();
});
// Test API : récupération des tâches
test('api returns paginated tasks', function () {
$user = User::factory()->create();
Task::factory()->count(20)->for($user)->create();
$response = $this->actingAs($user, 'sanctum')
->getJson('/api/tasks?per_page=10');
$response->assertOk()
->assertJsonCount(10, 'data')
->assertJsonStructure([
'data' => [
'*' => ['id', 'title', 'status', 'priority', 'due_date'],
],
'links',
'meta',
]);
});Exécution des tests avec Pest.
# terminal
# Exécution de tous les tests
php artisan test
# Tests avec couverture de code
php artisan test --coverage
# Tests d'un fichier spécifique
php artisan test tests/Feature/TaskTest.php
# Tests en parallèle (plus rapide)
php artisan test --parallelOptimisations pour la production
Avant le déploiement, plusieurs optimisations améliorent les performances de l'application Laravel.
# terminal
# Cache de la configuration
php artisan config:cache
# Cache des routes
php artisan route:cache
# Cache des vues
php artisan view:cache
# Optimisation de l'autoloader Composer
composer install --optimize-autoloader --no-dev
# Génération du manifest des assets
npm run buildConfiguration du fichier .env pour la production
# .env.production
APP_NAME="Task Manager"
APP_ENV=production
APP_DEBUG=false
APP_URL=https://taskmanager.example.com
# Cache et session via Redis (recommandé)
CACHE_DRIVER=redis
SESSION_DRIVER=redis
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
# Base de données
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_DATABASE=task_manager_prod
DB_USERNAME=app_user
DB_PASSWORD=strong_password_here
# Mail
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailgun.org
MAIL_PORT=587
MAIL_USERNAME=postmaster@taskmanager.example.com
MAIL_PASSWORD=secret
MAIL_ENCRYPTION=tlsNe jamais commiter le fichier .env dans le dépôt Git. Utilisez .env.example comme modèle et configurez les variables sensibles directement sur le serveur de production ou via des secrets managers.
Conclusion
Laravel 11 simplifie considérablement le développement PHP moderne avec sa structure allégée et ses conventions intelligentes. Ce guide a couvert les fondamentaux pour créer une application complète : modèles Eloquent, authentification, contrôleurs RESTful, policies d'autorisation, API avec Sanctum et tests automatisés.
Checklist pour une application Laravel de qualité
- ✅ Utiliser les migrations pour toutes les modifications de schéma
- ✅ Implémenter des policies pour sécuriser l'accès aux ressources
- ✅ Valider toutes les entrées utilisateur dans les contrôleurs
- ✅ Utiliser les ressources API pour contrôler les données exposées
- ✅ Écrire des tests pour les fonctionnalités critiques
- ✅ Configurer le cache et les optimisations avant le déploiement
- ✅ Sécuriser les variables d'environnement sensibles
Passe à la pratique !
Teste tes connaissances avec nos simulateurs d'entretien et tests techniques.
L'écosystème Laravel continue d'évoluer avec des packages comme Livewire pour les interfaces réactives, Horizon pour la gestion des queues, et Octane pour des performances exceptionnelles. La maîtrise de ces fondamentaux ouvre la porte à des applications PHP robustes et maintenables.
Tags
Partager
Articles similaires

Eloquent ORM : Patterns et optimisations pour Laravel
Maîtrisez Eloquent ORM avec les patterns avancés et techniques d'optimisation. Eager loading, query scopes, accessors, mutators et performance pour applications Laravel.

Questions d'entretien Laravel et PHP : Top 25 en 2026
Les 25 questions d'entretien Laravel et PHP les plus posées. Eloquent ORM, middleware, artisan, queues, tests et architecture avec réponses détaillées et exemples de code.

Laravel Middleware en profondeur : Authentification, Rate Limiting et Middleware personnalisé
Exploration complète des middleware Laravel avec des exemples pratiques : gardes d'authentification, limitation de débit avec throttle, création de middleware personnalisé et patterns avancés pour les applications en production.