Simplifier nos routes avec des contrôleurs

Dans ce tutoriel, nous allons ranger notre fichier routes/web.php dans plusieurs nouveaux fichiers nommés des « contrôleurs ».

Architecture MVC

L'architecture MVC est utilisé dans de nombreux frameworks web (en PHP ou dans d'autres langages), et permet d'organiser notre code en 3 grandes catégories.

Models, les modèles

Les modèles sont les fichiers et les fonctions permettant d'intéragir avec notre base de données. Dans notre application Laravel, cela correspond à notre fichier app/Utilisateur.php.

Views, les vues

Les vues permettent de gérer l'affichage de notre application. Se sont nos fichiers .blade.php dans notre dossier ressources/views.

Controllers, les contrôleurs

Les contrôleurs sont le reste de notre application PHP, ils vont se charger de faire le lien entre nos modèles et nos vues. Pour le moment, les contrôleurs sont représentés par notre fonctions anonymes dans le fichier routes/web.php.

Notre premier contrôleur

Nos vues et nos modèles sont plutôt bien rangés. Une vue par page, un modèle par table dans notre base de données. Nos contrôleurs, eux, sont plutôt tous en vrac dans le fichier routes/web.php. Nous allons donc créer un fichier « contrôleur » par thématique comme par exemple : l'inscription, la gestion des utilisateurs, l'accueil…

Pour créer notre premier contrôleur nous allons appeler la commande Laravel php artisan make:controller UtilisateursController. Puis nous rendre dans le nouveau fichier créé, qui est une simple classe PHP, à l'emplacement app/Http/Controllers/UtilisateursController.php.

Dans cette classe, nous pouvons mettre plusieurs méthode pour plusieurs pages liées. Dans notre cas, nous avons une seule page de gestion des utilisateurs, celle qui liste les adresses e-mail. Nous allons donc créer une simple méthode liste() et la remplir avec le contenu de la fonction anonyme située dans routes/web.php.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class UtilisateursController extends Controller
{
    public function liste()
    {
        $utilisateurs = App\Utilisateur::all();

        return view('utilisateurs', [
            'utilisateurs' => $utilisateurs,
        ]);
    }
}

Nous pouvons maintenant supprimer notre fonction anonyme et dire à Laravel d'utiliser notre nouveau contrôleur :

Route::get('/utilisateurs', 'UtilisateursController@liste');

Par défaut, Laravel va chercher le contrôleur dans app/Http/Controllers. Nous spécifions également après le @, que la fonction à appeler est liste.

Si nous essayons ce code, nous obtenons une erreur PHP car la classe Utilisateur est introuvable. Lorsque nous sommes dans un namespace (comme c'est le cas avec notre contrôleur dans le namespace App\Http\Controllers), PHP cherche les classes directement sous ce namespace, d'où la recherche de la classe Utilisateur dans App\Http\Controllers\App\Utilisateur. Pour lui dire de cherche de manière absolue depuis la racine du site, nous pouvons ajouter un \ avant le chemin : \App\Utilisateur::all(). Ou nous pouvons inclure la classe utilisateur avec un use de la même manière que le use Illuminate\Http\Request;. Dans ce cas, nous pouvons simplement utiliser Utilisateur sans spécifier le chemin complet.

<?php

namespace App\Http\Controllers;

use App\Utilisateur;

class UtilisateursController extends Controller
{
    public function liste()
    {
        $utilisateurs = Utilisateur::all();

        return view('utilisateurs', [
            'utilisateurs' => $utilisateurs,
        ]);
    }
}

Créer le contrôleur pour l'inscription

Nous allons procéder de la même manière pour l'inscription en créant un nouveau contrôleur avec php artisan make:controller InscriptionController puis en le remplissant avec le contenu des fonctions anonymes et en corrigeant le chemin vers Utilisateur.

<?php

namespace App\Http\Controllers;

use App\Utilisateur;

class InscriptionController extends Controller
{
    public function formulaire()
    {
        return view('inscription');
    }

    public function traitement()
    {
        request()->validate([
            'email' => ['required', 'email'],
            'password' => ['required', 'confirmed', 'min:8'],
            'password_confirmation' => ['required'],
        ], [
            'password.min' => 'Pour des raisons de sécurité, votre mot de passe doit faire :min caractères.'
        ]);

        $utilisateur = Utilisateur::create([
            'email' => request('email'),
            'mot_de_passe' => bcrypt(request('password')),
        ]);

        return "Nous avons reçu votre email qui est " . request('email') . ' et votre mot de passe est ' . request('password');
    }
}

Nous devons également changer nos routes :

Route::get('/inscription', 'InscriptionController@formulaire');
Route::post('/inscription', 'InscriptionController@traitement');

Les dernières routes

Nous pouvons supprimer les routes vers /bonjour/ et /a-propos qui ne nous sont plus utile. Pour la page d'accueil, au lieu de créer un contrôleur pour simplement return view('welcome'), Laravel nous fournit un raccourci avec la fonction Route::view().

Route::view('/', 'welcome');

Cette fonction charge la vue welcome lorsque nous nous rendons sur l'URL /.