Raoull
Membre
Messages : 442
Groupe : Membre
Inscription : Oct 2006
Statut :
Hors ligne
Réputation : 8
|
Classe Mysql
Une classe Mysql, une de plus, mais qui présente, je crois, quelques nouveautés.
Je me suis inspiré d'une classe assez simple trouvée sur ce site : http://classes.scriptsphp.org/source.mysql
J'ai viré le "ramasse-mettes"/cache, qui réclame une autre classe, et j'ai ajouté 2 choses :
1) Un tableau qui contient toutes les requetes qu'on effectue, leur résultat, insert_id, etc.
2) Un systeme de "requete dynamique" qui n'est en fait qu'une utilisation de sprintf, avec un mysql_real_escape_string sur les chaines, et qui permet de réutiliser une requete en ne faisant varier que les variables.
Cette classe ne contient pas toutes les possibilités de mysql, mais seulement les plus utiles.
Je la teste depuis un moment, et tout fonctionne bien. Mais ce n'est pas une version définitive. J'y travaille sans cesse, corrige les quelques bogues qui surviennent quand je la pousse à fond.
La fonction de debugf est "assez lourde", un simple print_r suffirait sans doute.
Je la mettrai à jour régulièrement.
Mais je vous la présente car elle peut sans doute servir, mais surtout j'aimerai vos remarques et améliorartions possibles.
Utilisation
Cette classe gère donc une unique connexion.
La connexion se fait lors de la première requete à la base, et se ferme lors de la desctrution de l'objet (ou explicitement via la fonction close).
Chaque requete porte un nom (unique ou non), et est stoqué dans le tableau $tabreq par ce nom, qui sera un tableau (2eme dimension) contenant :
- query : la requete sql
- result_id : la ressource résultat
- error : l'erreur mysql_error
- insert_id : le dernier id généré (INSERT)
- dynquery : la requete dynamque
- dynvars : les variables dynamiques
Exemples
A noter pour ces exemple, qu'ils ne sont pas vraiment à suivre en fait car il vaut mieux de pas utiliser les variables $_POST directement dans la requete, mais plustot tester avant si elles sont viables (vides, erreur, etc.) ; mais ce sont de simples exemples...
Exemple 1
// insertion classe, création de l'objet include("class.mysql.php"); $bdd = new mysql('server', 'login', 'pass', 'base');
// (optionnel) je me connecte, en spécifiant une autre base $bdd->connect('autre_base');
// --- une requete simple $bdd->query('req_1', 'SELECT id, nom, ville FROM table');
// -- :respect:affiche les résultats dans une boucle, via un mysql_fetch_assoc (par défaut dans get_array()) while($data = $bdd->get_array('req_1')) { echo $data['id'].' . '.data['nom'].' habite à '.data['ville'].'<br />'; }
// (optionnel) on déconnecte $bdd->close();
Exemple 2
include("class.mysql.php"); $bdd = new mysql('server', 'login', 'pass', 'base');
// --- une requete dynamique simple, d'apres "ville_1" reçu dans un formulaire $bdd->dynquery( 'req_1', // nom de la requete "SELECT id, nom FROM table WHERE ville='%s'", // requete dynamique (format sprintf) $_POST['ville_1'], // une seule variable, on la met direct 1 // on echappe les variables chaines (c notre cas) avec mysql_real_escape_string );
// -- exploitation résultats ...
// -- on veut faire la meme requete, mais avec une autre ville (ville_2)
// on change uniquement la variable $bdd->set_dynvars( 'req_1', // nom de la requete : le meme $_POST['ville_2'] // une seule variable, on la met direct );
// on réexécute la requete $bdd->do_dynquery( 'req_1', // nom de la requete 1 // on echappe la variable puisque chaine (surtout d'un formulaire) );
// -- exploitation resultats ...
// -- nb de requete dans le tableau (ici 1 seule) echo 'On a utilisé '.$bdd->nb_req().' requète(s) différente(s)<br />';
// -- nb de requete exécutées (ici 2) echo 'On a exécuté '.$bdd->$nb_req_sql.' requète(s)<br />';
// -- déboguage de la requete : affiche toutes les infos et l'éventuelle erreur sur cette requete echo $bdd->debug('req_1').'<br />;
// -- affiche l'éventuelle erreur dnas une requete // généralement mysql_error() echo $bdd->get_error('req_1');
// -- affiche l'éventuelle erreur générale dans la classe // par exemple exécution d'une requete qui n'existe pas, etc. echo $bdd->get_error();
Exemple 3
// --- requète dynamique avec plusieurs variables $bdd->dynquery( 'req_1', // nom de la requete "SELECT * FROM table WHERE nom='%s' AND age=%d AND ville='%s'", // requete dynamique (format sprintf) array( // pluisieurs variables, on utilise un tableau trim($_POST['nom']), intval($_POST['age']), trim($_POST['ville']), ), 1 // on echappe les variables chaines );
Pour déboguer toutes les requètes envoyées au serveur, et traquer les doublons :
echo '<pre>'; print_r($bdd->tabreqdebug); echo '</pre>';
Je ne mets pas d'exemple pour toutes les fonctions de la classe, je pense qu'elles sont suffisement explicites et commentées.
La classe
/************************************************* Projet : - Fichier : class.mysql.php Version : 0.8 (jeudi 8 mars 2007) **************************************************/
class Mysql {
/************************************************* variables **************************************************/
// identifiant de la connexion private $connect_id = 0;
// tableau des requètes private $tabreq = NULL;
// erreur générale private $error = '';
// nb de requètes effectuées à la base SQL public $nb_req_sql = 0;
public $tabreqdebug = array();
// ********** CONSTRUCTEUR / DESTRUCTEUR ****************************************
/************************************************* Constructeur ************************************************** host : adresse du serveur sql user : login pass : mot de passe base : base à sélectionner **************************************************/ public function __construct($host = 'localhost', $user = 'root', $pass = '', $base = '') { $this->host = $host; $this->user = $user; $this->pass = $pass; $this->base = $base;
$this->tabreq = array(); }
/************************************************* Destructeur ferme la connexion (si besoin) et détruit le tableau de requète - mysql_close - musql_free_result **************************************************/ function __destruct() { // libère la mémoire de toutes les requètes $ret = $this->del_allquery();
// ferme la connexion (si besoin) $this->close();
// supprime le tableau de requete unset($tabreq);
}
// ********** GESTION DES ERREURS ****************************************
/************************************************* PBLIC get_error : renvoie la dernière erreur générale ou la dernière erreur d'une requète ************************************************** reqid : nom de la requete **************************************************/ public function get_error($reqid = 'default') { if ($reqid == '') { // retourne la dernière erreur de la classe return $this->error; } else { // retourne la dernière erreur associée à une requete du tableau if (isset($this->tabreq[$reqid]['error'])) { return $this->tabreq[$reqid]['error']; } else { // erreur : la requete n'existe pas return FALSE; } } }
// ********** CONNEXION / DÉCONNEXION SQL ****************************************
/************************************************* PUBLIC is_connect : Renvoie l'état de la connexion connecté = TRUE, non connecté = FALSE **************************************************/ public function is_connect() { if ($this->connect_id) { return TRUE; } else { return FALSE; } }
/************************************************* PUBLIC : connexion explicite, choix de la base - mysql_connect - mysql_select_db ************************************************** base : nouvelle base à sélectionner (autre que celle précisé lors de la cération de l'objet **************************************************/ public function connect($base = '') { // changement de la base de données if ($base != '') { $this->base->$base; }
if (!$this->connect_id) { // connexion $connect = @mysql_connect($this->host, $this->user, $this->pass); if ($connect) { if (@mysql_select_db($this->base, $connect)) { $this->connect_id = $connect; return TRUE; } else { // erreur de la selection de la bdd die('Connexion impossible à la base de données : '.mysql_error()); return FALSE; } } else { // erreur lors de la connexion à la bdd die('Connexion impossible à la base de données : '.mysql_error()); return FALSE; } } else { // déjà connecté return FALSE; } }
/************************************************* PUBLIC : ferme la connection (fait automatiquement dans le destructeur) - mysql_close **************************************************/ public function close() { if ($this->connect_id) { // on déconnecte if (mysql_close($this->connect_id)) { $this->connect_id = 0; return TRUE; } else { // erreur lors de la déconnexion return FALSE; } } else { // on était pas connecté return TRUE; } }
// ********** GESTION DES REQUETES DYNAMIQUES(DANS LE TABLEAU DE REQUETE) ***********************
/************************************************* PUBLIC : exécute une requete dynamique ************************************************** reqid : nom de la requete dquery : requete sql au fomat sprintf dvars : expression (1 seule var) ou array, contenant la(es) variable(s) à inserer dans la requète eescape_string : (0/1) effetue un mysql_real_escape_string sur les variables qui sont des chaines **************************************************/ public function dynquery($reqid = 'default', $dquery = '', $dvars = NULL, $escape_string = 0) { // stocke la requete dynamique $this->set_dynquery($reqid, $dquery);
// stocke les variables dynamiques $ret = $this->set_dynvars($reqid, $dvars); if ($ret === TRUE) { // exécute la requete dynamqiue return $this->do_dynquery($reqid, $escape_string); } else { // erreur dans le stockage des variables return $ret; } }
/************************************************* PUBLIC : stocke une requete dynamique dans une requete du tableau (sans l'exécuter) si la requete n'existe pas dans le tableau, elle est créée ************************************************** reqid : nom de la requete dquery : requete sql au fomat sprintf **************************************************/ public function set_dynquery($reqid = 'default', $dquery = '') { if (isset($this->tabreq[$reqid])) { // si requete existe bien
// stocke la nouvelle requete dynamique $this->tabreq[$reqid]['dynquery'] = $dquery;
return 1; } else { // la requete n'existe pas dans le tableau ... on la créé
// créé une nouvelle requete $this->tabreq[$reqid] = array();
// initialise la nouvelle requete $this->tabreq[$reqid]['query'] = ''; $this->tabreq[$reqid]['dynquery'] = $dquery; $this->tabreq[$reqid]['dynvars'] = array(); $this->tabreq[$reqid]['error'] = '';
return 2; } }
/************************************************* PUBLIC : stocke les variables dynamique dans une requete du tableau (sans l'exécuter) la requete doit exister dans le tableau, et sa requete dynamique aussi ! ************************************************** reqid : nom de la requete dvars : expression (1 seule var) ou array, contenant le(s) variable(s) à inserer dans la requète **************************************************/ public function set_dynvars($reqid = 'default', $dvars = NULL) { if (!is_null($dvars)) { if (isset($this->tabreq[$reqid])) {
if (isset($this->tabreq[$reqid]['dynquery'])) {
// (ré)initialise le tableau des vars dynamques $this->tabreq[$reqid]['dynvars'] = array();
// on passe les variables au tableau if (is_array($dvars)) { // c'est un tableau $this->tabreq[$reqid]['dynvars'] = $dvars; } else { // pas 1 tableau : 1 seule var $this->tabreq[$reqid]['dynvars'][0] = $dvars; }
return TRUE; } else { // la requete dynamique n'existe pas... return -3; } } else { // la requete n'existe pas... return -2; } } else { // erreur $dvars n'a pas été fourni... return -1; } }
/************************************************* PUBLIC : renvoie le nombre de variable dynamique ************************************************** reqid : nom de la requete **************************************************/ public function num_dynvars($reqid = 'default') { if (isset($this->tabreq[$reqid]['dynvars'])) { return count($this->tabreq[$reqid]['dynvars']); } else { return -1; } }
/************************************************* PUBLIC : Exécute une requete dynamique, en option echappe les chaines avec mysql_real_escape_string - mysql_query ************************************************** reqid : nom de la requete eescape_string : (0/1) effetue un mysql_real_escape_string sur les variables qui sont des chaines **************************************************/ public function do_dynquery($reqid = 'default', $escape_string = 0) {
// vérifie l'existence de la requete dynamqiue if (isset($this->tabreq[$reqid]['dynquery'])) { // ok, requete existe
if ($escape_string == 1) { // échappe les chaines de caratères
// on se connecte au besoin if (!$this->connect_id) { $this->connect(); }
for ($i=0; $i<count($this->tabreq[$reqid]['dynvars']); $i++) { $arg = $this->tabreq[$reqid]['dynvars'][$i]; if (is_string($arg)) { $this->tabreq[$reqid]['dynvars'][$i] = mysql_real_escape_string($arg); } } }
// éxécute les variables dynamqiues $query = vsprintf($this->tabreq[$reqid]['dynquery'], $this->tabreq[$reqid]['dynvars']);
// stocke la requete finale $this->tabreq[$reqid]['query'] = $query;
// on execute la requete $ret = $this->do_query($reqid); return $ret;
} else { // requete n'existe pas $this->tabreq[$reqid]['error'] = 'la requète "'.$reqid.'" n\'existe pas...'; return FALSE; } }
// ********** GESTION DES REQUETES (DANS LE TABLEAU DE REQUETE) ***********************
/************************************************* PUBLIC : stocke une nouvelle requete (sans l'exécuter) ************************************************** reqid : nom de la requete query : requete sql au fomat sprintf **************************************************/ public function set_query($reqid = 'default', $query = '') {
// supprime la requete si elle existe deja if (isset($this->tabreq[$reqid])) { $this->del_query($reqid); $ret = 2; } else { $ret = 1; }
// créé une nouvelle requete $this->tabreq[$reqid] = array();
// initialise la nouvelle requete $this->tabreq[$reqid]['query'] = $query; $this->tabreq[$reqid]['error'] = '';
return TRUE; }
/************************************************* PUBLIC : Supprime une requete du tableau de requete - mysql_free_result ************************************************** reqid : nom de la requete **************************************************/ public function del_query($reqid = 'default') { // si la requete existe on la vire if (isset($this->tabreq[$reqid])) { if (isset($this->tabreq[$reqid]['result_id'])) { @mysql_free_result($this->tabreq[$reqid]['result_id']); } unset($this->tabreq[$reqid]); return TRUE; } else { return FALSE; } }
/************************************************* PUBLIC : Supprime toutes les requetes du tableau de requete - mysql_free_result (fait automatiquement dans le destructeur) **************************************************/ public function del_allquery() { $ret = 0; foreach($this->tabreq as $key => $value) { if (isset($this->tabreq[$key]['result_id'])) { @mysql_free_result($this->tabreq[$key]['result_id']); unset($this->tabreq[$key]); $ret++; } } return $ret; }
// ********** EXÉCUTION DES REQUÈTES *******************************************
/************************************************* PUBLIC : Créé et exécute une requete - mysql_query - mysql_insert_id (si INSERT) ************************************************** reqid : nom de la requete query : requete sql **************************************************/ public function query($reqid = 'default', $query = '') {
// on se connecte au besoin if (!$this->connect_id) { $this->connect(); }
// créé une nouvelle requète (supprime donc l'ancienne au besoin) $this->tabreq[$reqid] = array();
// initialise la nouvelle requète $this->tabreq[$reqid]['query'] = $query; $this->tabreq[$reqid]['error'] = '';
// on lance la requete et stocke le résultat if ($this->tabreq[$reqid]['result_id'] = mysql_query($query, $this->connect_id) ) {
$this->nb_req_sql++; $this->tabreqdebug[$reqid][] = $query;
// -- tente de stocker mysql_insert_id si la requete est un INSERT if (preg_match('`^insert`i', $this->tabreq[$reqid]['query'])) { $this->tabreq[$reqid]['insert_id'] = mysql_insert_id(); } return $this->tabreq[$reqid]['result_id']; } else { // erreur, on la stocke dans 'error' $this->tabreq[$reqid]['error'] = mysql_error(); return FALSE; } }
/************************************************* PUBLIC : Ré-exécute une requete a la DB - mysql_query - mysql_insert_id (si INSERT) ************************************************** reqid : nom de la requete **************************************************/ public function do_query($reqid = 'default') {
// vérifie l'existence de la requete if (isset($this->tabreq[$reqid]['query'])) { // ok, requete existe
// on se connecte si besoin if (!$this->connect_id) { $this->connect(); }
// réinitialise le tableau pour la requete $this->tabreq[$reqid]['error'] = ''; if (isset($this->tabreq[$reqid]['insert_id'])) { unset($this->tabreq[$reqid]['insert_id']); } if (isset($this->tabreq[$reqid]['result_id'])) { // optionnel... ? //@mysql_free_result($this->tabreq[$reqid]['result_id']); unset($this->tabreq[$reqid]['result_id']); }
// on lance la requete et stocke le résultat if ($this->tabreq[$reqid]['result_id'] = mysql_query($this->tabreq[$reqid]['query'], $this->connect_id) ) {
$this->nb_req_sql++; $this->tabreqdebug[$reqid][] = $this->tabreq[$reqid]['query'];
// -- tente de stocker mysql_insert_id si la requete est un INSERT if (preg_match('`^insert`i', $this->tabreq[$reqid]['query'])) { $this->tabreq[$reqid]['insert_id'] = mysql_insert_id(); }
return $this->tabreq[$reqid]['result_id']; } else { // erreur, on la stocke dans 'error' $this->tabreq[$reqid]['error'] = mysql_error(); return FALSE; } } else { // requete n'existe pas $this->tabreq[$reqid]['error'] = 'la requète "'.$reqid.'" n\'existe pas...'; return FALSE; } }
// ********** GESTION DES RÉSULTATS *******************************************
/************************************************* PUBLIC : renvoie le contenu d'un champ depuis un résultat SQL - mysql_result ************************************************** reqid : nom de la requete rows : numero de la ligne field : nom du champs **************************************************/ public function get_result($reqid = 'default', $rows = 0, $field = '') { if (isset($this->tabreq[$reqid]['result_id'])) { if ($field == '') { return @mysql_result($this->tabreq[$reqid]['result_id'], $row); } else { return @mysql_result($this->tabreq[$reqid]['result_id'], $row, $field); } } else { // pas de résultat trouvé (et/ou requete inexistante) return FALSE; } }
/************************************************* PUBLIC : renvoie un tableau qui contient la ligne demandée depuis un résultat SQL - mysql_fetch_object ************************************************** reqid : nom de la requete **************************************************/ public function get_object($reqid = 'default') { if (isset($this->tabreq[$reqid]['result_id'])) { return @mysql_fetch_object($this->tabreq[$reqid]['result_id']); } else { // pas de résultat trouvé (et/ou requete inexistante) return FALSE; } }
/************************************************* PUBLIC : renvoie un tableau depuis un résultat SQL - mysql_fetch_array - mysql_fetch_assoc ************************************************** reqid : nom de la requete mode : type de tableau renvoyé : - ASSOC (défault) : tableau associatif - NUM : tableau numérique - BOTH : les deux **************************************************/ public function get_array($reqid = 'default', $mode = 'ASSOC') { if (isset($this->tabreq[$reqid]['result_id'])) { switch($mode) { case 'NUM' : // tableau numérique return @mysql_fetch_array($this->tabreq[$reqid]['result_id'], MYSQL_NUM); break; case 'BOTH' : // tableau numérique ET tableau associatif return @mysql_fetch_array($this->tabreq[$reqid]['result_id'], MYSQL_BOTH); break; case 'ASSOC' : // tableau associatif default : return @mysql_fetch_assoc($this->tabreq[$reqid]['result_id']); } } else { // pas de résultat trouvé (et/ou requete inexistante) return FALSE; } }
/************************************************* PUBLIC : renvoie le nombre d'enregistrement affecté depuis un résultat SQL - mysql_num_rows : select - mysql_affected_rows : insert, update, replace, delete ************************************************** reqid : nom de la requete **************************************************/ public function num_rows($reqid = 'default') { if (isset($this->tabreq[$reqid]['result_id']) && $this->tabreq[$reqid]['result_id']) { if (preg_match('`^select`i', $this->tabreq[$reqid]['query'])) { // après un SELECT return mysql_num_rows($this->tabreq[$reqid]['result_id']); } elseif (preg_match('`^(insert|update|replace|delete)`i', $this->tabreq[$reqid]['query'])) { // après un INSERT / UPDATE / REPLACE / DELETE return mysql_affected_rows($this->connect_id); } } else { // pas de résultat trouvé (et/ou requete inexistante) return FALSE; } }
/************************************************* PUBLIC : renvoie l'id (auto-increment) généré par une requète, si INSERT - mysql_insert_id ************************************************** reqid : nom de la requete **************************************************/ public function insert_id($reqid = 'default') { if (isset($this->tabreq[$reqid]['insert_id'])) { return $this->tabreq[$reqid]['insert_id']; } else { // pas de résultat trouvé (et/ou insert_id inexistant) return FALSE; } }
/************************************************* PUBLIC : renvoie toutes les infos sur une requète, à des fins de déboguage ************************************************** reqid : nom de la requete **************************************************/ public function debug($reqid = 'default') { $debug = ''; if (isset($this->tabreq[$reqid])) { $debug .= '<br /><span style="color:#FF0000"><strong>DEBUG Mysql :</strong></span> '.$reqid.'<br /><br />'; // query if (isset($this->tabreq[$reqid]['query'])) { $debug .= 'Requète : '.$this->tabreq[$reqid]['query'].'<br /><br />'; }  
| |