Mini-cours de PHP - MySQL

Partie III

Après avoir étudié SQLite, les bases du langage SQL n'ont plus de secret pour vous. Vous savez comment écrire une requête SQL pour ajouter un enregistrement, le supprimer, le modifier, le sélectionner. À la fin de ce chapitre, vous aurez appris à envoyer n'importe quelle requête SQL à MySQL via du code PHP.

MySQL est comme SQLite un gestionnaire de bases de données. Tous deux utilisent le même langage SQL. SQLite est mono-base et mono-utilisateur. MySQL est multi-bases et multi-utilisateurs. Avec MySQL, des centaines d'utilisateurs peuvent travailler en même temps, sur des dizaines de bases de données, des milliers de tables, des millions d'enregistrements.

Avec MySQL, on peut gérer les commandes de clients, donner un accès sécurisé à certains membres de votre école, d'une association, d'une entreprise, d'un État, ...

Bien qu'il soit possible de créer une base de données, via une suite de requêtes SQL, nous allons apprendre à la créer bien plus facilement via une interface graphique très pratique : phpMyAdmin

phpMyAdmin

phpMyAdmin est une application web, écrite en PHP, qui permet de gérer des bases de données. Elle est formidable, car grâce à elle, vous allez pouvoir gérer vos bases de données en quelques clics.

Pour votre confort - pour vous éviter d'utiliser deux fenêtres de votre écran en même temps, l'une pour lire les présentes instructions et l'autre pour créer votre première table - cliquez ici et imprimez les instructions.

Exporter

Après avoir créé sa base de données en local et l'avoir testé avec des fichiers PHP, on souhaitera la placer on-line (= sur un "vrai" serveur). Au lieu de recréer la base manuellement, il est plus simple et plus sûr d'exporter la structure de cette base de données.

La structure d'une DB est l'ensemble des définitions des tables, des colonnes, des index, ...

Exporter la structure de sa base de données est très simple.

  1. Sélectionner la base de données
  2. Cliquer sur l'onglet "Export"
  3. Sélectionner l'option "Personnalisée"
  4. Dans la section "Tables", dans le champ "Tout sélectionner", décocher "Données"
  5. Cliquer sur le bouton "Exécuter" (en bas de page)
Ne modifier les autres options que pour les découvrir.

Votre navigateur télécharge un fichier texte ayant comme nom celui de votre base de données et comme extension .sql et l'enregistre dans le dossier "Téléchargement" désigné lors de la configuration de votre navigateur.

Pour situer exactement l'emplacement de ce dossier dans votre disque dur, consulter les "paramètres" de votre navigateur.

Suppression d'une base de données

Maintenant que vous savez créer des bases de données, des tables et les exporter, vous allez supprimer la base de données que vous avez créé pour la remplacer, via importation, par une base de données, toute faite, de même nom, qui sera utilisée jusqu'à la fin de ce mini-cours.

Pour en savoir plus sur phpMyAdmin, cliquez ici.

Ne supprimez pas les bases de données :

  1. information_schema
  2. mysql
  3. performance_schema
  4. sys

Ces bases de données sont créés lors de l'installation du serveur MySQL qui les utilise pour son bon fonctionnement.

Ne supprimez pas une base de données que vous n'avez pas créée, sauf si vous en assumez seul la totale responsabilité. Il n'existe pas de "Corbeille" qui vous permettrait de récupérer ce qui a été supprimé. Sur un serveur, supprimer cela veut dire ... supprimer [définitivement !]

Supprimer une base de données est très facile (et est une opération irréversible). Dans la colonne de gauche, sélectionner la base de données. Puis, dans la colonne de droite, en haut, cliquez sur l'onglet "Opérations", Puis, déroulez la fenêtre à mi-hauteur, puis cliquez sur le lien "Supprimer la base de données (DROP)"

Importer

On n'importe (via phpMyAdmin) que ce qui a été exporté (via phpMyAdmin).
On évite de chipoter dans un fichier .sql avec un éditeur de texte (sauf si on sait ce qu'on fait)

Contenu du fichier tests.sql :

Pour afficher le fichier "tests.sql", cliquez ici
Pour le télécharger, faites un clic droit, puis choisissez "Enregistrer ce lien sous ..."

Extensions possibles pour un fichier texte : txt, htm, html, css, js, php, sql, ...
Tous ces fichiers peuvent être lus et modifiés par NotePad++.

Sur le serveur, créez une base de données nommée : "tests".

Vous pouvez créer une base avec le nom que vous voulez, mais dans ce cas, il faudra modifier le fichier téléchargé (tests.sql) en modifiant la ligne (22)
-- Base de données : `tests`
par le nom que vous avez choisi.

En affichant le fichier téléchargé (tests.sql), vous constaterez que le nom de chaque table est préfixé par thi_.

Vous pouvez changer de préfixe, voir le supprimer. Dans ce cas, il vous faudra effectuer 22 remplacements (ou suppression)

Ces éventuelles modifications au niveau nom de la base et préfixes des tables étant faits, vous allez importer ce fichier (tests.sql) :

  1. Sélectionner la base de données créée.
  2. Cliquer sur l'onglet "Import"
  3. Dans la section : "Fichier à importer", cliquez sur "Choisir un fichier"
  4. Choisir un fichier .sql à importer
  5. Cliquer sur le bouton "Exécuter" (en bas de page)

Ne sélectionner d'autres options d'importation que si on sait ce qu'on fait.

Si tout s'est bien déroulé, s'affiche : "L'importation a réussi, 23 requêtes exécutées"

Fichier PHP de connexion

Sous Wamp, vérifiez que l'extension PHP php_pdo_mysql soit cochée. Pour faire cette vérification, clic gauche sur le W vert > PHP > Extensions PHP, dans la longue liste vérifiez la présence d'un V vert face à ce nom d'extension.

Sous Xampp, cette extension est active par défaut.

Cette vérification peut être faite en affichant la page web phpinfo.php et en y cherchant pdo_mysql (dans la section MySQL, comme API extension).

Pour nous connecter à cette base de données "tests", nous allons créer un fichier PHP : maConnexion.php
<?php

$typDB="mysql";

// <variables à mettre à jour>-----------------------------------

$host="localhost";
$dbname="tests"; // ou par le nom que vous avez choisi
$root="root";
$password=""; // ou le mot de passe de root donné lors de l'installation de MySQL
$prefixT="thi_"; // ou préfixe que vous avez choisi

// </variables à mettre à jour>-----------------------------------

$cnx=$typDB.":host=".$host.";dbname=".$dbname;
try { $bdd = new PDO($cnx, $root, $password); }
catch (Exception $e) { die('Erreur : ' . $e->getMessage()); }

$bdd->exec('SET NAMES utf8');

?>

Ne vous préoccupez que des 5 lignes de code situées dans la zone "variables à mettre à jour". Ne touchez pas aux autres. Ce code PHP est valable pour toutes les bases de données MySQL, (si l'extension PHP "php_pdo_mysql" est activée et si la base de données reçoit des informations codées en UTF-8, via un formulaire)

$host="localhost";
$dbname="tests";
$root="root";
$password="";
$prefixT="thi_";

localhost = lorsque vous construisez votre site web dynamique sur votre ordinateur.
tests = nom de la base de données que vous visez
root = nom d'utilisateur de la base de données
= mot de passe de l'utilisateur de la base de données
thi_ = préfixe des tables

Si vous mettez en ligne (sur internet) votre site web, il faudra modifier ces valeurs par celles fournies par votre fournisseur.

Le préfixe des tables ne sert pas à la connexion à la base de données. La plupart vous permettent - dans l'offre de base - d'utiliser qu'une seule base de données. Préfixer le nom de vos tables permet de faire tourner plusieurs applications sur la même base (et ainsi réaliser une petite économie financière).

$cnx=$typDB.":host=".$host.";dbname=".$dbname;
try { $bdd = new PDO($cnx, $root, $password); }
catch (Exception $e) { die('Erreur : ' . $e->getMessage()); }

$bdd->exec('SET NAMES utf8');

Si la connexion à la base de données (ici, "tests") échoue, un message d'erreur s'affichera et le contenu à afficher sur la page web s'arrête.

Après la connexion réussie à la base de données, la base de données est informée que toutes les données textuelles envoyées seront codées en UTF-8 (sans BOM).

Téléchargez ici le fichier "connexion_DB_tests.txt"

Une fois connecté à la base de données, d'autres erreurs peuvent apparaître. L'inexistence de la table, d'une colonne, ...

Ajouter des données

Pour ajouter des données dans notre base de données, nous allons créer un formulaire (un fichier HTML), puis un fichier PHP qui traitera les données reçues.

Voici un formulaire très simple, un champ et un bouton :

          <form name="ajouter" id="ajouter" method="post" action="ajouterUnePhrase_ask.php">
          <p>
            <label for="phrase">Ma phrase :</label>
          </p>
          <p>
            <input type="text" name="phrase" id="phrase" size="40" placeholder="ma phrase"
            maxlength="40" required="required" pattern="[^\x22]+" title="Vous ne pouvez pas utiliser de guillemet" />
          </p>
          <p>
            <input name="envoi" value="Ajouter ma phrase" type="submit" />
          </p>
        </form>

On constate que les données seront envoyées au fichier ajouterUnePhrase_ask.php (= valeur de l'attribut 'action'), via la méthode post. Et, le champ s'appelle phrase (= valeur de l'attribut 'name').

Remarquez que, dans le champ nommé phrase (dans le code HTML, via l'attribut 'name'), le seul caractère interdit le guillement ("). x22 est le code hexadécimal du caractère (") dans une table UTF-8 (et ASCII). Vous comprendrez bientôt pourquoi il est interdit.

Pour accéder à ce formulaire, cliquez ici .

Voici le code PHP du fichier - ajouterUnePhrase_ask.php - qui va traiter les données reçues et afficher un message d'échec ou de réussite :

ajouterUnePhrase_ask.php (code complet) :

        <?php

        // --- récupération de la donnée
        $phrase=$_POST['phrase'];

        // --- connexion à la DB
        require("maConnexion.php");

        // --- requête SQL
        $table1=$prefixT."table1";
        $sql="INSERT INTO $table1 (colonne1) VALUES (\"".$phrase."\");";
        $rep=$bdd->exec($sql);

        // --- informe l'utilisateur du résultat
        if ($rep===FALSE) { echo ("<p>La phrase n'a pas été ajoutée. </p>");}
        else{ echo "(<p>Votre phrase a été ajoutée dans la table 'table1'. </p>"); }

        ?>

Avant et après ce code PHP se trouve du code HTML. Ce code HTML est le code classique d'une page web. Ce code PHP est placé dans le body. Ce code PHP sert à récupérer la valeur du champ du formulaire, à se connecter à la base de données, à tenter d'insérer un enregistrement dans la table1 et a informé l'utilisateur du succès ou de l'échec de l'opération.

Analysons ce code PHP.

$phrase=$_POST['phrase'];

Les données d'un formulaire, envoyées par la méthode POST, se trouvent toujours dans la super-variable $_POST.

Dans un tableau (non-associatif), la variable simple est identifiée par un index (commençant à zéro). La variable $_POST est un tableau associatif, la variable simple est alors identifiée par une clé. La clé est, dans ce cas, le nom du champ.

Maintenant, vous savez ce qu'est un tableau associatif. C'est un ensemble de clés/valeurs. À chaque clé correspond à une valeur. La clé est l'équivalent de l'index dans un tableau (non-associatif).

La valeur du champ nommé 'phrase' est récupérée dans la variable $phrase ainsi : $phrase = $_POST['phrase'];

require("maConnexion.php");

La fonction require() permet d'inclure du code PHP dans du code PHP. Ainsi, dans le code du fichier ajouterUnePhrase_ask.php on injecte le code du fichier maConnexion.php à l'endroit où se trouve cette fonction require().

Après cette instruction, il existe (ou pas) une connexion à la base de données.

Si la connexion n'a pas lieu, une erreur est affichée et le reste du code PHP ne sera pas exécuté. Par exemple :
Erreur : SQLSTATE[HY000] [1049] Base 'tests' inconnue

$table1=$prefixT."table1";
$sql="INSERT INTO $table1 (colonne1) VALUES (\"".$phrase."\");";

Le nom de la "table1" est préfixé. $table1 vaut "thi_table1".

On reconnaît le code SQL d'une requête d'insertion.

INSERT INTO thi_table1 (colonne1) VALUES (777);
aurait été une requête SQL valable si le champ colonne1 était de type nombre.

INSERT INTO thi_table1 (colonne1) VALUES ("Toto va à l'école.");
est une requête SQL valable (puisque colonne1 est de type chaîne de caractères).

Une requête SQL est une chaîne de caractères.

Une chaîne de caractères peut être placée dans une variable.
Dans ce cas, la chaîne est entourée d'un caractère spécial (") ou (').
Comme il est plus probable de trouver dans la chaîne le caractère ('), elle est entourée de (").

Or, la requête SQL contient ("). Ils doivent donc être échappés ainsi :

$ql="INSERT INTO thi_table1 (colonne1) VALUES (\"Toto va à l'école.\");";

Dans la ligne ci-dessus, le caractère (") apparaît 4 fois.
Le premier et le dernier signifie respectivement : début de la chaîne de caractères et fin de la chaîne
Le second (et troisième) ne doit pas signifier fin de la chaîne de caractères, mais simple guillemet.
Le sens du caractère (") doit donc changer (passer de fin de la chaîne de caractères à simple guillemet)
Le caractère d'échappement sert à modifier la signification du caractère qui suit.
Le caractère d'échappement est \ .

$phrase="Toto va à l'école.";
$var="aaabbbccc";
Si on veut remplacer bbb par la valeur de $phrase, il faut coder ainsi :
$var="aaa".$phrase."ccc"; (on fait un concaténation)

Donc, si on veut remplacer Toto va à l'école. par la valeur de $phrase dans la variable $sql, il faut faire une concaténation :
$ql="INSERT INTO thi_table1 (colonne1) VALUES (\"".$phrase."\");";

On comprend maintenant que si le contenu de la variable $phrase contient un guillemet, le contenu de la variable $sql ne sera plus une requête SQL. Ce qui provoquera une erreur. Pour garder un code PHP simple, le guillemet est un caractère interdit dans le champ du formulaire.

$rep=$bdd->exec($sql);

Ce code ne sera pas expliqué ! Mais, on constate qu'il utilise la variable $sql qui est une chaîne de caractères qui représente une requête SQL.

Ce code PHP demande au serveur MySQL d'exécuter la requête SQL.

if ($rep===FALSE) { echo ("<p>La phrase n'a pas été ajoutée. </p>");}
        else{ echo "(<p>Votre phrase a été ajoutée dans la table 'table1'. </p>"); }

Ce code n'est pas expliqué. Mais, on sait que l'exécution d'une requête SQL aboutit ou pas. Le if ... else affiche, via la fonction echo(), un message d'échec ou de réussite.

Ce fichier ne doit être appelé que via un clic sur le bouton de soumission du formulaire. Son appel direct provoque une erreur. Cliquez ici pour appeler ce fichier sans passer par le formulaire. L'erreur vient du fait que la variable $phrase contient NULL (puisque la super-variable $_POST ne contient rien, puisque rien n'a été envoyé via la méthode post). Or, $phrase est utilisé pour créer la variable $sql qui devient à son tour NULL (= propagation du NULL). Demander l'exécution d'une requête SQL qui vaut NULL provoque une erreur.

PHP doit être configuré sur le serveur de production pour ne pas afficher de messages d'erreur en cas d'erreur, pour éviter de donner des indications à des hackers. Contrairement à la configuration PHP sur un serveur de développement, où ces messages d'erreurs sont très utiles pour corriger les erreurs.

Récupérer des données

Pour vérifier que les données sont bien entrées, nous allons afficher tout le contenu de 'thi_table1' dans une page web appelée afficherTable1.php.

Rappel : Pour qu'un clic sur le lien appelant un fichier PHP ne provoque pas d'erreur, il faut que le PHP se trouve sur internet ou en localhost.

Voici le code PHP du fichier - afficherTable1.php - qui va interroger la base de données et afficher les réponses (une par ligne) :

        <?php

        // --- connexion à la DB
        require("maConnexion.php");

        // --- requête SQL
        $table1=$prefixT."table1";
        $sql="SELECT * FROM $table1;";
        $rep=$bdd->query($sql);

        // Affiche du contenu de table1
        while ($ligne = $rep->fetch())
        {
          echo("<p>".$ligne[0]."</p>");
        }

        ?>

On constate que la fonction require() est de nouveau utilisée (car il faut de nouveau se connecter à la base de données). On reconnaît la requête SQL de sélection. Et, on constate la présence d'une boucle while

On constate que la ligne qui suit la déclaration de la variable $sql est légèrement différente. Lorsqu'il s'agit d'une requête de sélection on utilise la fonction query(). Et, exec() dans les autres cas.

La condition de la boucle while n'est pas expliqué ! Mais, on constate, dans le corps de la boucle, que $ligne est une super-variable (qui contient le contenu de toutes les colonnes d'une ligne de 'thi_table1'). Comme l'index de la première colonne vaut 0, $ligne[0] représente un contenu de 'colonne1'.

Supprimer des données

Enfin, nous allons créer un fichier PHP chargé d'effacer la 'thi_table1'.

Voici le code PHP du fichier - effacerTable1.php - qui va tenter d'effacer le contenu de 'table1' et afficher un message d'échec ou de réussite (de l'effacement) :

        <?php

        // --- connexion à la DB
        require("maConnexion.php");

        // --- requête SQL
        $table1=$prefixT."table1";
        $sql="DELETE FROM $table1;";
        $rep=$bdd->exec($sql);

        // --- informe l'utilisateur du résultat
        if ($rep===FALSE) { echo("<p>Table1 pas effacée.</p>");}
        else{ echo("<p>Le contenu de table1 a été effacé.</p>"); }

        ?>

On constate que la fonction require() est de nouveau utilisée (car il faut de nouveau se connecter à la base de données). On reconnaît la requête SQL d'effacement du contenu d'une table.

Comme il ne s'agit pas d'une requête de sélection, on utilise la fonction exec(). Le if ... else suit toujours un exec(). Il affiche, via la fonction echo(), un message d'échec ou de réussite suite à l'envoi d'une requête d'exécution.


Maintenant, vous connaissez le code PHP à utiliser pour exécuter une requête SQL. Vous connaissez les bases du PHP-MYSQL. Ce mini-cours est donc terminé !

Vous connaissez les bases PHP-MySQL. Mais, auriez-vous pensé à interdire le guillemet (") ? Si non, vos connaissances en matière de sécurité sont alors quasi nulles, ce qui est normal pour un débutant.

Or, toute base de données, en production, doit être très très très fortement protégée.

Cliquez ici pour accéder à un formulaire qui n'interdit pas le guillemet dans le champ 'phrase'. Tapez une phrase avec un ou plusieurs guillemets. Puis, cliquez sur le bouton ...