Signification de CRUD : CRUD est un acronyme issu du monde de la programmation informatique qui fait référence aux quatre fonctions considérées comme nécessaires pour implémenter un stockage persistant dans votre application : créer (Create), lire (Read), mettre à jour (Update) et supprimer (Delete).
Nous allons créer une application CRUD pour les produits en utilisant Laravel 11 dans cet exemple. Nous allons créer une table products avec des colonnes name et detail à l’aide d’une migration Laravel 11. Ensuite, nous allons créer des routes, un contrôleur, des vues et des fichiers de modèle pour le module produit. Nous utiliserons Bootstrap 5 pour la conception. Suivez les étapes ci-dessous pour créer des opérations CRUD avec Laravel 11.
Étapes pour l’exemple d’opération CRUD avec Laravel 11
Installer Laravel 11
Configurer la base de données MySQL
Créer une migration
Créer une classe de validation de formulaire
Créer un contrôleur et un modèle
Ajouter une route ressource
Mettre à jour AppServiceProvider
Ajouter les fichiers Blade
Étape 1 : Installer Laravel 11
Tout d’abord, obtenez une nouvelle application Laravel 11 en exécutant la commande suivante :
composer create-project laravel/laravel example-app
Étape 2 : Configuration de la base de données MySQL
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=here your database name
DB_USERNAME=here database username(root)
DB_PASSWORD=here database password(root)
Étape 3 : Créer une migration
php artisan make:migration create_products_table --create=products
Ajoutez le code suivant au fichier de migration créé :
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->text('detail');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('products');
}
};
Exécutez la migration :
php artisan migrate
Étape 4 : Créer une classe de validation de formulaire
Créez une classe de validation pour store() et update() dans le contrôleur :
php artisan make:request ProductStoreRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ProductStoreRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array|string>
*/
public function rules(): array
{
return [
'name' => 'required',
'detail' => 'required'
];
}
}
php artisan make:request ProductUpdateRequest
Ajoutez les règles de validation dans les fichiers générés (ProductStoreRequest.php et ProductUpdateRequest.php) :
app/Http/Requests/ProductUpdateRequest.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class ProductUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array|string>
*/
public function rules(): array
{
return [
'name' => 'required',
'detail' => 'required'
];
}
}
Étape 5 : Créer un contrôleur et un modèle
Créez un contrôleur ressource :
artisan make:controller ProductController --resource --model=Product
Ajoutez le code suivant au contrôleur généré ProductController.php :
<?php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\View\View;
use App\Http\Requests\ProductStoreRequest;
use App\Http\Requests\ProductUpdateRequest;
class ProductController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(): View
{
$products = Product::latest()->paginate(5);
return view('products.index', compact('products'))
->with('i', (request()->input('page', 1) - 1) * 5);
}
/**
* Show the form for creating a new resource.
*/
public function create(): View
{
return view('products.create');
}
/**
* Store a newly created resource in storage.
*/
public function store(ProductStoreRequest $request): RedirectResponse
{
Product::create($request->validated());
return redirect()->route('products.index')
->with('success', 'Product created successfully.');
}
/**
* Display the specified resource.
*/
public function show(Product $product): View
{
return view('products.show',compact('product'));
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Product $product): View
{
return view('products.edit',compact('product'));
}
/**
* Update the specified resource in storage.
*/
public function update(ProductUpdateRequest $request, Product $product): RedirectResponse
{
$product->update($request->validated());
return redirect()->route('products.index')
->with('success','Product updated successfully');
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Product $product): RedirectResponse
{
$product->delete();
return redirect()->route('products.index')
->with('success','Product deleted successfully');
}
}
app/Models/Product.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
use HasFactory;
protected $fillable = [
'name',
'detail',
];
}
Étape 6 : Ajouter une route ressource
Ajoutez une route dans routes/web.php :
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
Route::get('/', function () {
return view('welcome');
});
Route::resource('products', ProductController::class);
Étape 7 : Mettre à jour AppServiceProvider
app/Provides/AppServiceProvider.php
Configurez Bootstrap 5 pour la pagination :
app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Pagination\Paginator;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Paginator::useBootstrapFive();
}
}
Étape 8 : Ajouter les fichiers Blade
resources/views/products/index.blade.php
@extends('products.layout')
@section('content')
<div class="card mt-5">
<h2 class="card-header">Laravel 11 CRUD Example from scratch - ItSolutionStuff.com</h2>
<div class="card-body">
@session('success')
<div class="alert alert-success" role="alert"> {{ $value }} </div>
@endsession
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a class="btn btn-success btn-sm" href="{{ route('products.create') }}"> <i class="fa fa-plus"></i> Create New Product</a>
</div>
<table class="table table-bordered table-striped mt-4">
<thead>
<tr>
<th width="80px">No</th>
<th>Name</th>
<th>Details</th>
<th width="250px">Action</th>
</tr>
</thead>
<tbody>
@forelse ($products as $product)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $product->name }}</td>
<td>{{ $product->detail }}</td>
<td>
<form action="{{ route('products.destroy',$product->id) }}" method="POST">
<a class="btn btn-info btn-sm" href="{{ route('products.show',$product->id) }}"><i class="fa-solid fa-list"></i> Show</a>
<a class="btn btn-primary btn-sm" href="{{ route('products.edit',$product->id) }}"><i class="fa-solid fa-pen-to-square"></i> Edit</a>
@csrf
@method('DELETE')
<button type="submit" class="btn btn-danger btn-sm"><i class="fa-solid fa-trash"></i> Delete</button>
</form>
</td>
</tr>
@empty
<tr>
<td colspan="4">There are no data.</td>
</tr>
@endforelse
</tbody>
</table>
{!! $products->links() !!}
</div>
</div>
@endsection
resources/views/products/create.blade.php
@extends('products.layout')
@section('content')
<div class="card mt-5">
<h2 class="card-header">Add New Product</h2>
<div class="card-body">
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
</div>
<form action="{{ route('products.store') }}" method="POST">
@csrf
<div class="mb-3">
<label for="inputName" class="form-label"><strong>Name:</strong></label>
<input
type="text"
name="name"
class="form-control @error('name') is-invalid @enderror"
id="inputName"
placeholder="Name">
@error('name')
<div class="form-text text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="inputDetail" class="form-label"><strong>Detail:</strong></label>
<textarea
class="form-control @error('detail') is-invalid @enderror"
style="height:150px"
name="detail"
id="inputDetail"
placeholder="Detail"></textarea>
@error('detail')
<div class="form-text text-danger">{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-success"><i class="fa-solid fa-floppy-disk"></i> Submit</button>
</form>
</div>
</div>
@endsection
resources/views/products/edit.blade.php
@extends('products.layout')
@section('content')
<div class="card mt-5">
<h2 class="card-header">Edit Product</h2>
<div class="card-body">
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
</div>
<form action="{{ route('products.update',$product->id) }}" method="POST">
@csrf
@method('PUT')
<div class="mb-3">
<label for="inputName" class="form-label"><strong>Name:</strong></label>
<input
type="text"
name="name"
value="{{ $product->name }}"
class="form-control @error('name') is-invalid @enderror"
id="inputName"
placeholder="Name">
@error('name')
<div class="form-text text-danger">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="inputDetail" class="form-label"><strong>Detail:</strong></label>
<textarea
class="form-control @error('detail') is-invalid @enderror"
style="height:150px"
name="detail"
id="inputDetail"
placeholder="Detail">{{ $product->detail }}</textarea>
@error('detail')
<div class="form-text text-danger">{{ $message }}</div>
@enderror
</div>
<button type="submit" class="btn btn-success"><i class="fa-solid fa-floppy-disk"></i> Update</button>
</form>
</div>
</div>
@endsection
resources/views/products/show.blade.php
@extends('products.layout')
@section('content')
<div class="card mt-5">
<h2 class="card-header">Show Product</h2>
<div class="card-body">
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a class="btn btn-primary btn-sm" href="{{ route('products.index') }}"><i class="fa fa-arrow-left"></i> Back</a>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12">
<div class="form-group">
<strong>Name:</strong> <br/>
{{ $product->name }}
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 mt-2">
<div class="form-group">
<strong>Details:</strong> <br/>
{{ $product->detail }}
</div>
</div>
</div>
</div>
</div>
@endsection
resources/views/products/layout.blade.php
<!DOCTYPE html>
<html>
<head>
<title>Laravel 11 CRUD Application - ItSolutionStuff.com</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" />
</head>
<body>
<div class="container">
@yield('content')
</div>
</body>
</html>
Exécution de l’application Laravel
php artisan serve
Accédez à l’application :
http://localhost:8000/products
Vous verrez des pages pour lister, ajouter, modifier et afficher les produits.