Leçons PHP - leçon 3.2 - Travail avec la base de données MySQL. Insertion de données INSERT INTO. Sélection de données SELECT
Dans la leçon précédente, nous avons créé une table pour notre site. Dans cette leçon, nous allons améliorer notre table et commencer à travailler avec la base de données : insérer des données et récupérer des données depuis la table. Je pense que cela ne sera pas trop compliqué, alors commençons.
Pour commencer, je propose d’améliorer notre table messages. Elle contient déjà des champs pour les données, mais il faut ajouter un champ pour numéroter les enregistrements. Si vous regardez dans la base Drupal, la table node a un champ nid qui sert à numéroter les nœuds. Nous allons faire pareil pour notre table messages.
Allons dans phpMyAdmin (http://localhost/tools/phpmyadmin pour Denwer) et modifions la table. Ajoutons une colonne au début de la table comme montré sur l’image :
Nommons la colonne mid (message id), type INT (entier) longueur 11. Cochez la case AUTO_INCREMENT, ce qui signifie que la numérotation se fait automatiquement. Mettez aussi l’index en PRIMARY KEY, ce qui en fait la clé primaire de la table.
Si vous vous souvenez, nous avions créé une méthode dans la classe simpleCMS pour créer la table. Nous allons modifier cette méthode pour qu’elle crée aussi le champ mid. Allez dans la table messages et cliquez sur Export :
Vous arrivez sur la page d’export de la table. L’export est sous forme de requêtes SQL pour créer et modifier la table. Si vous modifiez la table dans phpMyAdmin, vous pouvez copier la requête SQL de création, ce qui est très pratique.
Laissez tout par défaut et cliquez sur OK. phpMyAdmin vous donnera le code SQL dans le navigateur ou dans un fichier. Les deux conviennent. Copiez ce code :
Notez les backticks (`) utilisés par phpMyAdmin. En PHP, on peut utiliser des quotes simples. Collez ce texte dans la méthode buildDB() :
public function buildDB(){ $sql = "CREATE TABLE IF NOT EXISTS 'messages' ( 'mid' int(11) NOT NULL AUTO_INCREMENT, 'title' varchar(150) DEFAULT NULL, 'bodytext' text, 'created' varchar(100) DEFAULT NULL, PRIMARY KEY ('mid') ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; return mysql_query($sql); }
Testons maintenant. Supprimez la table messages :
Confirmez la suppression. Maintenant, quand vous lancerez index.php, la méthode buildDB() sera exécutée et la table sera recréée.
public function buildDB(){ $sql = "CREATE TABLE Messages ( mid int NOT NULL AUTO_INCREMENT, PRIMARY KEY(mid), title varchar(15), bodytext text, created int(11) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; $result = mysql_query($sql); print_r($result); }
Lancez index.php, la table Messages apparaît comme avant.
Requêtes d’insertion INSERT INTO
La base est créée, on peut maintenant écrire et afficher des messages en base. Commençons par l’écriture, modifions la méthode write() :
public function write($p) { // méthode d’écriture de message $sql = 'INSERT INTO Messages (title, bodytext, created) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ')'; return mysql_query($sql); }
Analysons l’insertion. La requête SQL commence par INSERT INTO, puis le nom de la table Messages. Ensuite on indique les colonnes dans lesquelles insérer les valeurs. Notez qu’on ne met pas mid car sa valeur est auto-incrémentée par MySQL. Ensuite vient VALUES suivi des valeurs à insérer, dans le même ordre que les colonnes.
Les valeurs textuelles doivent être entourées de guillemets différents de ceux encadrant la requête SQL. Par exemple :
"'. $p["title"] . '"
Le bon ordre est : guillemets doubles, guillemets simples, concaténation, variable, concaténation, guillemets simples, guillemets doubles.
Un seul exemple suffira ici, d’autres suivront. Remplacez la méthode write() par celle-ci.
Requêtes de sélection SELECT
Créez quelques lignes, vérifiez dans phpMyAdmin :
On peut maintenant afficher ces enregistrements avec display_public(), modifions cette méthode. On utilise SELECT pour récupérer les données :
public function display_public() { // méthode d’affichage des messages $content = ''; $sql = 'SELECT * FROM Messages'; // requête de sélection $result = mysql_query($sql); // résultat de la requête while($row = mysql_fetch_array($result)){ // traiter chaque ligne avec mysql_fetch_array() print '<div class="post">'; // div contenant le message print '<span class="time">#' . $row['mid'] . ' du ' . date('d-m-Y', $row['created']) . '</span><h2>' . $row['title'] . '</h2>'; // date et titre print '<p>' . $row['bodytext'] . '</p>'; // contenu du message print '</div>'; // fin du div } $content .= '<p><a href="/index.php?admin=1">Ajouter un message</a></p>'; return $content; }
Le SELECT commence par l’opérateur SELECT puis une étoile *, signifiant qu’on veut tous les champs. On peut aussi sélectionner certains champs :
$sql = 'SELECT mid,title FROM Messages'; // requête de sélection $result = mysql_query($sql);
Seuls mid et title seront sélectionnés, pas bodytext ni created.
Après * vient FROM qui indique la table.
Le résultat de mysql_query() doit être stocké, ici dans $result, car on va le traiter avec mysql_fetch_array().
Imaginez que la requête retourne 3 enregistrements. mysql_fetch_array() permet de récupérer un tableau par appel : au premier appel, le premier enregistrement, au deuxième appel, le second, etc. Quand il n’y a plus de lignes, la fonction retourne false. C’est pourquoi on utilise une boucle while. Ainsi, on traite chaque enregistrement jusqu’à la fin.
Cela peut être compliqué au début, mais on s’habitue vite. Peu d’opérateurs SQL à apprendre.
Tri des résultats avec ORDER BY
On peut trier les résultats avec ORDER BY. Par défaut, c’est un tri croissant, par exemple :
$sql = 'SELECT * FROM Messages ORDER BY mid';
On trie par mid croissant. Pour un tri décroissant, on ajoute DESC :
$sql = 'SELECT * FROM Messages ORDER BY mid DESC';
Pour un tri croissant explicite, on peut écrire :
$sql = 'SELECT * FROM Messages ORDER BY mid ASC';
Mais c’est la valeur par défaut.
Conditions avec WHERE
On peut filtrer les résultats avec WHERE :
$sql = 'SELECT * FROM Messages WHERE mid<3 ORDER BY mid DESC';
Cela sélectionne les deux premiers enregistrements (mid=1 et mid=2) s’ils existent. On peut combiner des conditions avec AND (et) et OR (ou). Avec AND, toutes les conditions doivent être vraies, avec OR, une suffit :
$limit_time = time() - 3600; // une heure avant $sql = 'SELECT * FROM Messages WHERE mid<3 AND created>' . $limit_time . ' ORDER BY mid DESC'; // requête de sélection
Cette requête sélectionne les messages avec mid 3 et créés il y a moins d’une heure. Je pense que c’est suffisant pour cette leçon, passons à la suivante.