Nouveau : Datasets open source gratuits disponibles !Decouvrir →
🐘
Intermediaire 30 min Laravel

Laravel avec PostgreSQL : guide pratique

Pourquoi Laravel avec PostgreSQL : guide pratique ?

Dans un monde où les applications web deviennent de plus en plus complexes, la gestion des données est cruciale pour l'efficacité et la performance de l'application. Laravel, bien connu pour sa simplicité et son efficacité, offre une intégration parfaite avec PostgreSQL, qui est un système de gestion de base de données relationnelle performant, extensible et open source. En utilisant Laravel avec PostgreSQL, vous pouvez tirer parti des avantages de ces deux technologies ensemble.

Un cas d'usage concret serait la création d'une application de gestion de tâches, où les fonctionnalités comme l'ajout, la modification et le suivi des tâches nécessitent une gestion efficace des données. Avec Laravel et PostgreSQL, vous pouvez créer une application robuste et performante pour gérer ces tâches.

Prerequis

  • Connaissance de base de PHP
  • Familiarité avec les concepts d'architecture MVC (Model-View-Controller)
  • Installation de Composer (gestionnaire de dépendances PHP)
  • Installation de Node.js (pour les outils front-end)
  • Installation de PostgreSQL
  • Installation de Laravel (via Composer)

Concepts fondamentaux

1. Migrations

Les migrations sont un moyen de définir et d'appliquer des modifications à votre base de données. Elles vous permettent de garder une trace historique de vos modifications et de les appliquer facilement sur n'importe quelle instance de la base de données.

## Création d'une migration pour créer une table 'tasks'
php artisan make:migration create_tasks_table --create=tasks

## Migration créée dans database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php
return new class extends Migration
{
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tasks');
    }
};

2. Eloquent ORM

Eloquent est un ORM (Object-Relational Mapping) intégré à Laravel qui vous permet de manipuler les données de la base de données en utilisant des objets PHP.

## Création d'un modèle 'Task'
php artisan make:model Task

## Model créé dans app/Models/Task.php
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'description', 'completed'];
}

## Utilisation du modèle pour créer une nouvelle tâche
use App\Models\Task;

$task = new Task();
$task->title = 'Faire les courses';
$task->save();

3. Factories

Les factories sont un moyen de générer des données de test et de développement. Elles vous permettent de créer des objets avec des valeurs aléatoires ou spécifiques.

## Création d'une factory pour le modèle 'Task'
php artisan make:factory TaskFactory --model=Task

## Factory créée dans database/factories/TaskFactory.php
namespace Database\Factories;

use App\Models\Task;
use Illuminate\Database\Eloquent\Factories\Factory;

class TaskFactory extends Factory
{
    protected $model = Task::class;

    public function definition()
    {
        return [
            'title' => fake()->sentence(),
            'description' => fake()->paragraph(),
            'completed' => fake()->boolean,
        ];
    }
}

## Utilisation de la factory pour créer une nouvelle tâche
use App\Models\Task;
use Database\Factories\TaskFactory;

$task = Task::factory()->create();

4. Relations

Les relations Eloquent vous permettent de définir des relations entre les modèles, comme les associations un-à-un, un-à-plusieurs et plusieurs-à-plusieurs.

## Ajout d'une relation 'user' dans le modèle 'Task'
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Task extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'description', 'completed'];

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

## Ajout d'une relation 'tasks' dans le modèle 'User'
namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Authenticatable
{
    use HasFactory;

    protected $fillable = ['name', 'email', 'password'];

    public function tasks(): HasMany
    {
        return $this->hasMany(Task::class);
    }
}

## Utilisation des relations dans le code
use App\Models\Task;
use App\Models\User;

$user = User::find(1);
$tasks = $user->tasks;

Mise en pratique : projet fil rouge

Étape 1 : Création du projet Laravel

composer create-project --prefer-dist laravel/laravel task-manager
cd task-manager
npm install
php artisan migrate

Étape 2 : Création des modèles et migrations

php artisan make:model Task -m
php artisan make:model User -m

Migration pour tasks :

## database/migrations/xxxx_xx_xx_xxxxxx_create_tasks_table.php
return new class extends Migration
{
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id')->constrained()->onDelete('cascade');
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tasks');
    }
};

Migration pour users :

## database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php
return new class extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
};

Étape 3 : Création des controllers

php artisan make:controller TaskController --resource
php artisan make:controller UserController --resource

Controller TaskController :

## app/Http/Controllers/TaskController.php
namespace App\Http\Controllers;

use App\Models\Task;
use Illuminate\Http\Request;

class TaskController extends Controller
{
    public function index()
    {
        $tasks = Task::all();
        return view('tasks.index', compact('tasks'));
    }

    public function create()
    {
        return view('tasks.create');
    }

    public function store(Request $request)
    {
        $task = new Task($request->all());
        $task->save();
        return redirect()->route('tasks.index');
    }

    public function show(Task $task)
    {
        return view('tasks.show', compact('task'));
    }

    public function edit(Task $task)
    {
        return view('tasks.edit', compact('task'));
    }

    public function update(Request $request, Task $task)
    {
        $task->update($request->all());
        return redirect()->route('tasks.index');
    }

    public function destroy(Task $task)
    {
        $task->delete();
        return redirect()->route('tasks.index');
    }
}

Controller UserController :

## app/Http/Controllers/UserController.php
namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index()
    {
        $users = User::all();
        return view('users.index', compact('users'));
    }

    public function create()
    {
        return view('users.create');
    }

    public function store(Request $request)
    {
        $user = new User($request->all());
        $user->save();
        return redirect()->route('users.index');
    }

    public function show(User $user)
    {
        return view('users.show', compact('user'));
    }

    public function edit(User $user)
    {
        return view('users.edit', compact('user'));
    }

    public function update(Request $request, User $user)
    {
        $user->update($request->all());
        return redirect()->route('users.index');
    }

    public function destroy(User $user)
    {
        $user->delete();
        return redirect()->route('users.index');
    }
}

Étape 4 : Création des vues

Vue resources/views/tasks/index.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Tâches</h1>
    <a href="route('tasks.create')" class="btn btn-primary mb-3">Nouvelle tâche</a>
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Titre</th>
                <th>Description</th>
                <th>Complétée</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach($tasks as $task)
                <tr>
                    <td>$task->id</td>
                    <td>$task->title</td>
                    <td>$task->description</td>
                    <td>$task->completed ? 'Oui' : 'Non'</td>
                    <td>
                        <a href="route('tasks.edit', $task)" class="btn btn-primary">Éditer</a>
                        <form action="route('tasks.destroy', $task)" method="POST" style="display: inline-block;">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger" onclick="return confirm('Êtes-vous sûr?')">Supprimer</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

Vue resources/views/tasks/create.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Nouvelle tâche</h1>
    <form action="route('tasks.store')" method="POST" enctype="multipart/form-data">
        @csrf
        <div class="mb-3">
            <label for="title" class="form-label">Titre</label>
            <input type="text" name="title" id="title" class="form-control" required>
        </div>
        <div class="mb-3">
            <label for="description" class="form-label">Description</label>
            <textarea name="description" id="description" class="form-control"></textarea>
        </div>
        <div class="mb-3">
            <label for="completed" class="form-label">Complétée</label>
            <input type="checkbox" name="completed" id="completed" value="1">
        </div>
        <button type="submit" class="btn btn-primary">Enregistrer</button>
    </form>
</div>
@endsection

Vue resources/views/tasks/edit.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Éditer tâche</h1>
    <form action="route('tasks.update', $task)" method="POST" enctype="multipart/form-data">
        @csrf
        @method('PUT')
        <div class="mb-3">
            <label for="title" class="form-label">Titre</label>
            <input type="text" name="title" id="title" class="form-control" value="$task->title" required>
        </div>
        <div class="mb-3">
            <label for="description" class="form-label">Description</label>
            <textarea name="description" id="description" class="form-control">$task->description</textarea>
        </div>
        <div class="mb-3">
            <label for="completed" class="form-label">Complétée</label>
            <input type="checkbox" name="completed" id="completed" value="1" $task->completed ? 'checked' : ''>
        </div>
        <button type="submit" class="btn btn-primary">Enregistrer</button>
    </form>
</div>
@endsection

Vue resources/views/users/index.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Utilisateurs</h1>
    <a href="route('users.create')" class="btn btn-primary mb-3">Nouvel utilisateur</a>
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Nom</th>
                <th>Email</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach($users as $user)
                <tr>
                    <td>$user->id</td>
                    <td>$user->name</td>
                    <td>$user->email</td>
                    <td>
                        <a href="route('users.edit', $user)" class="btn btn-primary">Éditer</a>
                        <form action="route('users.destroy', $user)" method="POST" style="display: inline-block;">
                            @csrf
                            @method('DELETE')
                            <button type="submit" class="btn btn-danger" onclick="return confirm('Êtes-vous sûr?')">Supprimer</button>
                        </form>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>
@endsection

Vue resources/views/users/create.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Nouvel utilisateur</h1>
    <form action="route('users.store')" method="POST" enctype="multipart/form-data">
        @csrf
        <div class="mb-3">
            <label for="name" class="form-label">Nom</label>
            <input type="text" name="name" id="name" class="form-control" required>
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" name="email" id="email" class="form-control" required>
        </div>
        <div class="mb-3">
            <label for="password" class="form-label">Mot de passe</label>
            <input type="password" name="password" id="password" class="form-control" required>
        </div>
        <button type="submit" class="btn btn-primary">Enregistrer</button>
    </form>
</div>
@endsection

Vue resources/views/users/edit.blade.php :

@extends('layouts.app')

@section('content')
<div class="container">
    <h1>Éditer utilisateur</h1>
    <form action="route('users.update', $user)" method="POST" enctype="multipart/form-data">
        @csrf
        @method('PUT')
        <div class="mb-3">
            <label for="name" class="form-label">Nom</label>
            <input type="text" name="name" id="name" class="form-control" value="$user->name" required>
        </div>
        <div class="mb-3">
            <label for="email" class="form-label">Email</label>
            <input type="email" name="email" id="email" class="form-control" value="$user->email" required>
        </div>
        <button type="submit" class="btn btn-primary">Enregistrer</button>
    </form>
</div>
@endsection

Étape 5 : Configuration des routes

Fichier routes/web.php :

use App\Http\Controllers\TaskController;
use App\Http\Controllers\UserController;

Route::resource('tasks', TaskController::class);
Route::resource('users', UserController::class);

Étape 6 : Création des migrations et du modèle

Migration pour la table tasks :

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTasksTable extends Migration
{
    public function up()
    {
        Schema::create('tasks', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('description')->nullable();
            $table->boolean('completed')->default(false);
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('tasks');
    }
}

Migration pour la table users :

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Modèle Task :

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    protected $fillable = ['title', 'description', 'completed'];
}

Modèle User :

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    protected $hidden = [
        'password',
        'remember_token',
    ];
}

Étape 7 : Migration des bases de données

php artisan migrate

Étape 8 : Création d'un utilisateur administrateur (facultatif)

php artisan tinker
$User = new App\Models\User;
$User->name = 'admin';
$User->email = 'admin@example.com';
$User->password = bcrypt('password');
$User->save();

Étape 9 : Configuration de l'authentification (facultatif)

Fichier config/auth.php :

return [
    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],
];

Fichier routes/web.php :

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\Auth\LogoutController;

Route::get('login', [LoginController::class, 'showLoginForm'])->name('login');
Route::post('login', [LoginController::class, 'login']);
Route::post('logout', [LogoutController::class, 'logout'])->name('logout');

Route::middleware(['auth'])->group(function () {
    Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
});

Fichier app/Http/Controllers/Auth/LoginController.php :

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo = '/home';

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

Fichier app/Http/Controllers/Auth/LogoutController.php :

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\LogsOutUsers;

class LogoutController extends Controller
{
    use LogsOutUsers;

    protected $guard = 'web';

    protected function redirectTo()
    {
        return '/login';
    }
}

Étape 10 : Création de la vue de base

Vue resources/views/layouts/app.blade.php :

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Application</title>
    <link href="asset('css/app.css')" rel="stylesheet">
</head>
<body>
    @yield('content')
</body>
</html>

Étape 11 : Compilation des assets (facultatif)

npm install
npm run dev

Conclusion

Vous avez maintenant une application Laravel avec PostgreSQL, gérant les tâches et les utilisateurs. Vous pouvez personnaliser davantage l'application en ajoutant d'autres fonctionnalités et en améliorant la sécurité. N'oubliez pas de tester soigneusement toutes les fonctionnalités pour vous assurer qu'elles fonctionnent correctement.

N'hésitez pas à poser des questions ou à partager vos commentaires si vous avez besoin d'aide supplémentaire!

Besoin d'aide sur Laravel ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment installer Laravel avec PostgreSQL?
Pour installer Laravel avec PostgreSQL, commencez par créer un nouveau projet Laravel en utilisant la commande 'composer create-project --prefer-dist laravel/laravel nom_du_projet'. Ensuite, configurez votre fichier .env pour utiliser PostgreSQL en modifiant les paramètres DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME et DB_PASSWORD.
Comment migrer des données d'une base de données MySQL à PostgreSQL?
Pour migrer vos données d'une base de données MySQL à PostgreSQL, vous pouvez utiliser des outils comme 'pgloader' ou écrire un script personnalisé en PHP pour exporter et importer les données. Assurez-vous également de vérifier la compatibilité des types de données entre les deux systèmes.
Quelles sont les meilleures pratiques pour utiliser Laravel avec PostgreSQL?
Utilisez le type de données approprié dans PostgreSQL pour chaque champ. Par exemple, utilisez 'jsonb' pour stocker des données JSON complexes. Assurez-vous de bien gérer les transactions et d'utiliser des index efficaces pour améliorer les performances des requêtes. Enfin, faites attention à la gestion des échappements des caractères spéciaux dans vos requêtes SQL.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.