Connexion à une base de données ; upload de fichiers

Licence Informatique 3ème année

Alexandre Niveau — Jean-Marc Lecarpentier

Enseignement des technologies du Web

 

Connexion à une base de données ; upload de fichiers

Notes de cours

Travail personnel

Objectifs

Le premier exercice vous guide dans l'utilisation d'une base de données dans le cadre de l'architecture MVCR. Le deuxième, optionnel, est une application directe de l'upload de fichiers.

Exercice 1 — Utilisation d’une base de données dans MVCR #

Dans cet exercice, on implémente simplement l'interface AnimalStorage (ou celle correspondant à vos objets) en utilisant une vraie base de données MySQL. J'en profite pour préciser quelques détails annexes, mais sur le fond il n'y a pas de surprise, c'est assez direct.

  1. Pour commencer, si ce n'est déjà fait, faire en sorte que l'instance de AnimalStorage manipulée par le contrôleur soit créée par animaux.php et passée comme argument au main du routeur, qui l'utilisera pour construire le contrôleur. L'idée est que la décision du type de stockage utilisé doit être prise par animaux.php, c'est-à-dire le véritable point d'entrée de l'application, pas quelque part au milieu du code.
  2. Créer une table dans une de vos bases de données MySQL qui contiendra les animaux/objets. Voir cette page de la FAQ du département pour savoir comment accéder à vos bases. À noter en particulier, votre mot de passe initial pour MySQL est dans le répertoire Protected de votre répertoire par défaut (/home/etudiants/LOGIN/Protected/mysql.txt). Vous pouvez utiliser (ou adapter) ce fichier, qui contient le code SQL permettant de créer une table animals avec les trois animaux de départ. Le plus simple pour ajouter la table à votre BD est d'utiliser la fonction d'import sur l'application phpMyAdmin, accessible à https://dev-LOGIN.users.info.unicaen.fr/phpmyadmin. Attention, il faudra a priori créer une base, et tous les noms ne sont pas autorisés !
  3. Créer une classe AnimalStorageMySQL dans src/model qui implémente AnimalStorage. Pour commencer, on construira l'instance de PDO dans le constructeur, et toutes les méthodes enverront une exception avec un message du genre « not yet implemented ».
  4. Remplacer l'instance de AnimalStorageFile que manipule le contrôleur par une instance de AnimalStorageMySQL ; normalement, il doit suffire de modifier animaux.php. Aller sur la page affichant la liste des animaux/objets : vous devez voir votre exception « not yet implemented ».
  5. On va implémenter readAll() en premier ; mais avant d'écrire la vraie requête, écrire une requête syntactiquement fausse, par exemple SELECTE ETOILE;. Retourner sur la page affichant la liste des animaux/objets : vous devez toujours avoir une exception, mais cette fois due à une erreur de syntaxe SQL. Si ce n'est pas le cas, c'est que vous n'avez pas activé le bon mode de gestion des erreurs ! Faites-le avant de continuer !
  6. À présent, écrire la requête correcte dans readAll() pour récupérer tous les animaux/objets de la base. Attention, il ne suffira pas de renvoyer le résultat : readAll() est supposée renvoyer un tableau d'instance de la classe Animal. C'est à vous de créer ce tableau, à partir des données « brutes » renvoyées par PDO.
  7. Retourner sur la page affichant la liste des animaux/objets : elle doit maintenant fonctionner comme avant. Évidemment, si vous cliquez sur l'un deux, la page individuelle ne fonctionnera pas puisque la méthode read($id) n'est pas encore implémentée. Pas d'urgence : continuez d'abord l'exercice.
  8. Il n'est pas propre de construire l'instance de PDO dans AnimalStorageMySQL : si on a plusieurs classes de ce type, on va construire plusieurs instances de PDO et donc ouvrir plusieurs connexions à la BD, ce qui est inefficace. Modifier le code pour que l'instance de PDO soit créée dans animaux.php et passée en argument au constructeur de AnimalStorageMySQL.
  9. Pour l'instant, on a mis les paramètres de connexion à la BD dans animaux.php, notamment le mot de passe. C'est embêtant si on veut montrer notre code ou le mettre sur un dépôt. Créer un fichier mysql_config.php dans le répertoire private qui se trouve à la racine de votre compte web (à côté de www-prod et www-dev). Y déclarer des constantes MYSQL_HOST, MYSQL_PORT, MYSQL_DB, MYSQL_USER et MYSQL_PASSWORD.
  10. Dans animaux.php, ajouter require_once('/users/LOGIN/private/mysql_config.php'); et utiliser les constantes pour construire l'instance de PDO. L'intérêt est que le fichier mysql_config.php est inaccessible depuis le web, ce qui garantit une bonne sécurité pour vos identifiants. Vos scripts PHP y ont accès car ils sont sur la même machine.
  11. Vérifier que la page avec la liste fonctionne toujours, puis implémenter la méthode read($id) de AnimalStorageMySQL.
  12. Vérifier que les pages animaux.php?id=1, animaux.php?id=2 et animaux.php?id=3 (ou équivalentes) fonctionnent à nouveau.
  13. Que se passe-t-il si vous utilisez l'URL animaux.php?id=bla'bla (avec une apostrophe au milieu) ? Normalement, votre site devrait vous dire que l'animal/objet n'existe pas. S'il y a une erreur SQL, c'est très probablement que votre code est vulnérable aux injections SQL. Modifier le code de read($id) pour utiliser des requêtes préparées.
  14. Implémenter ensuite les autres méthodes de AnimalStorageMySQL, toujours en prenant soin d'utiliser des requêtes préparées.

Exercice 2 (optionnel) — Dépôt de fichiers #

Si vous êtes en difficulté et/ou êtes en retard sur le TP MVCR, laissez tomber cet exercice.
NB: l’upload de fichiers ne sera pas au programme du TP noté.

Créer un script affichant un formulaire permettant de déposer une image sur le serveur. Après le dépôt, la page devra montrer l'image déposée pendant toute la session de l'internaute (on parle bien de session au sens PHP : pas d'authentification ici !).

Attention, chaque internaute devra avoir sa propre image : vous pouvez tester facilement en utilisant deux navigateurs différents. En particulier, que se passe-t-il si deux internautes déposent une image de même nom ?