17:4431122007
Clearbricks : quelques autres fonctions de dbLayer
Par Moe - Site / Dév
Dans le billet d'introduction (qu'il est préférable d'avoir lu avant d'aborder ce billet) nous avons vu comment effectuer des requêtes avec la fonction select() de dbLayer. Après avoir découvert comment lire les enregistrements dans la base de données, nous allons ici voir comment insérer, mettre à jour et effacer des enregistrements.
Voici pour rappel la table des lecteurs que nous avons utilisé comme exemple dans le billet d'introduction :
La table lecteurs
| id | nom | role |
|---|---|---|
| 1 | Pierre | clown |
| 2 | Paul | développeur |
| 3 | Jacques | soutien moral |
| 4 | Olivier | chef |
| 5 | Kozlika | fée |
Le curseur
Pour insérer ou mettre à jour un enregistrement avec dbLayer, il faut d'abord ouvrir un curseur. Cela se fait avec la commande openCursor() et permet de définir sur quelle table on va agir. Ici ce sera la table lecteurs.
Ouvrons un curseur :
$cur = $con->openCursor('lecteurs');
$cur est un cursor, ou curseur en français. Nous allons lui attribuer des variables qui correspondent aux colonnes de la table et des valeurs grâce à la syntaxe suivante :
$cur->variable = valeur;
Exemples :
Pour définir le nom :
$cur->nom = 'César';
Pour définir le rôle :
$cur->role = 'empereur';
Insérer un enregistrement avec la fonction insert()
Un nouveau lecteur est arrivé, il s'appelle Hector et son rôle est "évangéliste". Comment faire pour l'ajouter à la table des lecteurs ? On ouvre un curseur, on lui attribue des valeurs :
$cur = $con->openCursor('lecteurs'); $cur->nom = 'Hector'; $cur->role = 'évangéliste';
Ensuite on utilise la fonction insert(), elle va récupérer les variables et les valeurs pour les insérer dans la table :
$cur->insert();
Voici le code complet :
$cur = $con->openCursor('lecteurs'); $cur->nom = 'Hector'; $cur->role = 'évangéliste'; $cur->insert();
Et la table après l'insertion :
| id | nom | role |
|---|---|---|
| 1 | Pierre | clown |
| 2 | Paul | développeur |
| 3 | Jacques | soutien moral |
| 4 | Olivier | chef |
| 5 | Kozlika | fée |
| 6 | Hector | évangéliste |
Un enregistrement a été créé. Notez que l'id de cet enregistrement vaut 6 car la base de données a été configurée pour incrémenter l'id à chaque nouvel enregistrement.
Modifier un enregistrement avec la fonction update()
Pierre n'est plus clown, il est devenu professeur. Comment mettre à jour l'enregistrement de la table qui le concerne ? On ouvre un curseur et on attribue les nouvelles valeurs :
$cur = $con->openCursor('lecteurs'); $cur->role = 'professeur';
Puis on utilise la fonction update(), Le mot-clé WHERE permet de définir quel enregistrement nous allons mettre à jour, ici on veut modifier l'enregistrement de Pierre donc nous allons sélectionner l'enregistrement où le nom est "Pierre" :
$cur->update('WHERE nom = \'Pierre\';');
Voici le code complet :
$cur = $con->openCursor('lecteurs'); $cur->role = 'professeur'; $cur->update('WHERE nom = \'Pierre\';');
Et le résultat :
| id | nom | role |
|---|---|---|
| 1 | Pierre | professeur |
| 2 | Paul | développeur |
| 3 | Jacques | soutien moral |
| 4 | Olivier | chef |
| 5 | Kozlika | fée |
| 6 | Hector | évangéliste |
L'enregistrement a été mis à jour.
Effacer un enregistrement avec la fonction execute()
Il n'y a pas de fonction spéciale pour effacer un enregistrement, nous allons utiliser la commande execute() qui sert à exécuter des requêtes SQL.
Jacques n'est plus lecteur, Comment effacer l'enregistrement qui le concerne ? Voici la requête SQL qui va effacer l'enregistrement avec l'id 3 : DELETE FROM lecteurs WHERE id = 3;
On exécute la requête :
$query = 'DELETE FROM lecteurs WHERE id = 3;'; $con->execute($query);
Et la table devient :
| id | nom | role |
|---|---|---|
| 1 | Pierre | professeur |
| 2 | Paul | développeur |
| 4 | Olivier | chef |
| 5 | Kozlika | fée |
| 6 | Hector | évangéliste |
Notez qu'on aurait pu réaliser la même action avec cette requête SQL :
$query = 'DELETE FROM lecteurs WHERE nom = \'Jacques\';';
Quelques fonctions supplémentaires pour les recordsets
Ces fonctions permettent d'obtenir des informations sur les requêtes SELECT décrites dans le billet d'introduction.
isEmpty()
Cette fonction retourne true si un recordset est vide ou false sinon. Elle s'utilise dans une condition, pour voir si un recordset contient des enregistrements. Ici on va afficher les noms des lecteurs dont l'id est supérieur à 3 :
$query = 'SELECT nom FROM lecteurs WHERE id > 3;'; $rs = $con->select($query); if ($rs->isEmpty()) { echo('aucun lecteur'); } else { while ($rs->fetch()) {echo($rs->f('nom').' ');} }
Ce code affichera "aucun lecteur" si le recordset est vide et affichera les noms des lecteurs s'il y en a.
Pour ne pas afficher de message spécifique en cas de recordset vide on utilisera le code suivant :
$query = 'SELECT nom FROM lecteurs WHERE id > 3;'; $rs = $con->select($query); if (!$rs->isEmpty()) { while ($rs->fetch()) {echo($rs->f('nom').' ');} }
count()
Cette fonction retourne le nombre d'enregistrements présents dans un recordset :
$query = 'SELECT nom FROM lecteurs WHERE id > 3;'; $rs = $con->select($query); echo('nombre d\'enregistrements : '.$rs->count());
Ceci affichera par exemple "nombre d'enregistrements : 2".
Conclusion
Grâce au billet précédent et à ce billet, vous savez lire et modifier des enregistrements dans des tables d'une base de données. Pour apprendre comment créer ou modifier des tables, voyez la documentation de Dotclear. Vous êtes prêts à gérer des tables dans une base de données avec Clearbricks.
Commentaires
Deux petits détails qui, à mon avis, mériteraient d'être corrigés ou modifiés.
En premier, dans le texte d'introduction, il y a une légère faute de frappe : « ... découvert comme lire... » devrait être « ... découvert comment lire ... »
Ensuite, dans le paragraphe intitulé « Le curseur, » il y a un problème avec l'exemple. On commence par ouvrir un curseur sur la table lecteurs, puis on attribue une valeur à des champs (age, couleur, ...) qui n'existent pas dans la table. J'ai le sentiment que cela va rendre l'exemple confus pour un débutant.
Autrement, bravo pour cet effort de documentation qui profitera à un grand nombre.
Merci d'avoir corrigé ces erreurs, tu as raison pour les exemples, je les ai remplacés par d'autres exemples en rapport avec la table
lecteurs.bonjour,
savez-vous comment récupérer l'ID du dernier élément enregistré via $cursor ?
j'ai beau épluché le code des différentes class, je ne trouve pas de possibilité de le faire, ce que je trouve étrange.
@loïc m. : j'ai regardé aussi le code et je ne vois rien de tel. Il faut utiliser :
$id = $con->select('SELECT MAX(id) FROM '.$table.';')->f(0);Ensuite pour faire une aute insertion il faut incrémenter cet id :
$cur = $con->openCursor('lecteurs');$cur->id = $id+1;
$cur->insert();
Dans mon billet, j'utilise MySQL et l'ID est automatiquement ajouté par auto_increment, sous PostgreSQL il faut utiliser le code que je viens de donner.
je me réponds direct :
mysql_insert_id($con->link())je ne pense pas avoir mieux à proposer...
@Moe : en effet c'est une solution, mais je rpéfère utiliser ma solution avec MySQL.
Quid d'une double insertion simultané avec ta méthode ?
Faut d'abord locker la table, faire l'insertion, release ?
P.S: je viens de relire mon premier reply, désolé pour les qqs fautes :/
@loïc m. : si c'est pour utiliser dans un plugin Dotclear, la fonction mysql_insert_id() ne fonctionnera pas avec PostgreSQL, il vaut mieux passer seulement par Clearbricks. Si c'est pour un autre projet avec MySQL seulement, pourquoi pas.
J'ai pris ce code dans la fonction dcBlog::addPost(). Il existe un risque qu'il soit fait 2 appels en même temps à la base de données mais en pratique la durée entre la lecture du dernier enregistrement et l'enregistrement du nouveau se mesure en milli-secondes. Il faudrait un gros coup de malchance pour que 2 requêtes arrivent au même moment. Plus il y a d'utilisateurs, plus le risque augmente, mais sur un blog perso on risque rien.
@loïc m. : j'ai demandé à olivier, il m'a informé que ça pouvait poser des gros problèmes si il y a beaucoup de requêtes simultanées.
@moe : merci pour toutes tes réponses.
je travail en effet sur un projet qui tourne uniquement sous mysql, donc ma solution me convient.
Ta solution posera des problèmes en cas de fort trafique de ton appli, c'est certain.
Je n'ai d'ailleurs jamais été favorable à de telle pratique pour récupérer l'ID inséré.
Pour ma part, ce risque existe au vu de mon parc utilisateur susceptible d'utiliser mon appli.
Sinon pour PostgreSQL, je pense avoir trouvé un équivalent :
manuel php.net
forum php
Recherche Google 'PostgreSQL mysql_insert_id'
Bonjour,
je reviens vers vous pour une autre question.
J'aimerai sur une requête SELECT, construire un tableau associatif de type
$array[$key]=$valueLa solution que j'ai trouvé, pour un résultat unique est :
$q='SELECT id, nom, prenom, role FROM lecteurs WHERE id='.$idUser; $rs = $con->select($q); foreach($rs->columns() as $index=>$value) { $dataUser[$value]=$rs->f($value); }Le but de ce code est de pouvoir générer un menu déroulant <select /> en faisant une boucle sur le tableau, avec pour chaque <option /> :
<option value="$value">$dataUser[$value]</option>Bonjour,
merci pour la mise en forme du code : je n'ai pas réussi à le mettre en forme dans mon commentaire.
Sinon le but de ce code est de pouvoir accéder aux données récupérées par le biais d'un tableau associatif $clef=$valeur.
Je sais parfaitement que ce n'est pas le plus joli à faire, surtout vu la logique de clearbricks.
Seulement lorsqu'on veut intégrer du nouveau code propre à du code existant, il faut s'adapter aux contraintes existantes : le tableau associatif.