Le fonctionnement de l'architecture est expliqué dans les cours précédents (architecture de base ; manipulation des données)
couleurs/ |-- skin/ | `-- screen.css |-- src/ | |-- ctl/ | | `-- Controller.php | |-- lib/ | | `-- ObjectFileDB.php | |-- model/ | | |-- ColorBuilder.php | | |-- Color.php | | |-- ColorStorageFile.php | | `-- ColorStorage.php | |-- view/ | | `-- MainView.php | `-- Router.php `-- index.php
Le résultat de notre CRUD basique est visible ici, et le code est disponible dans cette archive.
Notre site fonctionne, mais il n'est pas très robuste. On va voir à présent comment on peut améliorer son confort d'utilisation.
Solution : POST-redirect-GET
Les pages destinées à être accédées en POST ne doivent pas être visibles directement par les internautes.
Il faut les rediriger immédiatement vers une page normale.
La logique est que les utilisateurs ont l'habitude de GET, qui est idempotente : la même requête donne toujours le même résultat.
En redirigeant systématiquement après un POST, on donne à chaque méthode son rôle de base tel que défini par HTTP : POST modifie les données, GET affiche les données.
303 See Other
;
on peut utiliser une option de la fonction PHP header
:
header("Location: " . $url, true, 303);
Le POST-redirect-GET marche bien pour la création et la modification (sans erreur), car on redirige vers la page de la couleur
Pour la suppression, on voudrait pouvoir rediriger vers la galerie avec un feedback du type « La couleur a bien été supprimée »
Nécessite de se souvenir de ce qui s'est passé à la requête précédente : il faut utiliser les variables de session
$_SESSION["feedback"]
contient
le feedback de la requête précédente.
On va donc appliquer le POST-redirect-GET jusqu'au bout : si données invalides, on redirige vers la page de formulaire initiale
il faut donc enregistrer en session les données reçues et les erreurs à afficher.
Il suffit de stocker l'instance de ColorBuilder
dans une variable
comme $_SESSION['currentColorBuilder']
Lors de l'accès en GET
à une page de formulaire,
le contrôleur donne à la vue le ColorBuilder qui est dans cette variable.
On ne peut pas modifier une couleur existante si on a un ColorBuilder non validé en cours !
Pour le deuxième point, il suffit d'avoir une
variable de session $_SESSION['modifiedColors']
qui contient
un tableau d'instances de ColorBuilder
,
indexés par leur identifiant.
Grâce à cette modification, on a aussi amélioré l'utilisabilité de notre site, car les formulaires sont maintenant persistants : si un formulaire invalide a été soumis, il n'est pas perdu, même si on change de page.
En particulier, on peut éditer plusieurs couleurs en même temps sans risque que les différents formulaires s'écrasent entre eux.
Le résultat de toutes nos améliorations est visible ici, et le code est disponible dans cette archive.
On présente maintenant encore d'autres améliorations, pas forcément complexes à implémenter mais un peu moins fondamentales. On ne les abordera pas toutes en TP, mais elles sont recommandées sur un véritable site.
On a utilisé des URL particulières pour les POST,
mais on n'en a pas besoin :
on peut réutiliser action=creerCouleur
, action=modifier
et action=supprimer
, et vérifier si la page a été accédée
avec GET ou avec POST (on peut le voir dans $_SERVER["REQUEST_METHOD"]
Au lieu d'utiliser des paramètres GET pour les actions et les identifiants,
ce qui n'est pas propre, on peut exploiter la possibilité de mettre un chemin après le nom du script PHP dans l'URL, par ex index.php/couleurs/45
.
Ce chemin virtuel est récupérable grâce à la variable
$_SERVER["PATH_INFO"]
(attention, elle n'est pas présente s'il n'y a rien
après le nom du script)
Dans tous les cas, les URL vues par les internautes peuvent être différentes
des « vrais » chemins sur le serveur, grace à la réécriture d'URL.
Avec Apache, on utilise le module mod_rewrite
,
utilisable dans les .htaccess
.
Principe : le client demande l'URL /couleurs/08/modifier
,
mais le serveur appelle en fait le script avec
/couleurs/index.php?id=08&action=modifier
ou /couleurs/index.php/08/modifier
(en fonction de la technique utilisée dans votre architecture)
La syntaxe de mod_rewrite
est notoirement abominable :
moins vous l'utiliserez, mieux vous vous porterez.
Implémenter un retour à zéro pour les formulaires de modification (les champs sont réinitialisés à la valeur présente dans la BD)
Sur les pages accédées en POST, on peut vérifier que l'internaute est bien passé·e par notre formulaire, par exemple en mettant une sorte de jeton en session ⇒ empêche les attaques de type cross-site request forgery (CSRF)
Votre méthode :
case 'home':
$this->view->makeHomePage($person);
break;
public function getHomeURL() {
return $this->baseURL . "/home";
}
Slim Framework :
$app->get('/home', \App\controllers\ViewsController::class . ':home')->setName('home');
La méthode setName permettant de définir un nom qui sera utilisé dans les
href et submit. Ainsi on peu changer l'URL sans changer les liens dans chaque
fichiers.
\App\controllers\ViewsController::class permet de d'indiquer le namespace du
controller à utiliser et ':home' la méthode à utiliser.