JeuWeb - Crée ton jeu par navigateur
Classe Mysql - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Classe Mysql (/showthread.php?tid=916)



Classe Mysql - Raoull - 07-03-2007

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
Code PHP :
<?php 
// 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
Code PHP :
<?php 
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
Code PHP :
<?php 
// --- 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 :
Code PHP :
<?php 
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
Code PHP :
<?php 
/*************************************************
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 />';
}
else {
$debug .= 'Requète : -<br /><br />';
}
// dyn query
if (isset($this->tabreq[$reqid]['dynquery'])) {
$debug .= 'Requète dynamique : '.$this->tabreq[$reqid]['dynquery'].'<br /><br />';
}
else {
$debug .= 'Requète dynamique : -<br /><br />';
}
// dyn vars
if (isset($this->tabreq[$reqid]['dynvars'])) {
$debug .= 'Variables dynamiques : '.count($this->tabreq[$reqid]['dynvars']).'<br /><br />';
for (
$i=0; $i<count($this->tabreq[$reqid]['dynvars']); $i++) {
$debug .= 'Var '.$i.' : '.$this->tabreq[$reqid]['dynvars'][$i].'<br /><br />';
}
}
else {
$debug .= 'Variables dynamiques : -<br /><br />';
}
// result_id
if (isset($this->tabreq[$reqid]['result_id'])) {
$debug .= 'Ressource (result_id) : '.$this->tabreq[$reqid]['result_id'].'<br /><br />';
}
else {
$debug .= 'Ressource (result_id) : -<br /><br />';
}
// insert_id
if (isset($this->tabreq[$reqid]['insert_id'])) {
$debug .= 'Insert_id : '.$this->tabreq[$reqid]['insert_id'].'<br /><br />';
}
else {
$debug .= 'Insert_id : -<br /><br />';
}
// error
if (isset($this->tabreq[$reqid]['error'])) {
$debug .= 'Erreur : '.$this->tabreq[$reqid]['error'].'<br /><br />';
}
else {
$debug .= 'Erreur : -<br /><br />';
}
}
else {
// pas de résultat trouvé (et/ou insert_id inexistant)
$debug .= 'La requète '.$reqid.'n\'existe pas...<br /><br />';
}

$debug .= '<span style="color:#FF0000"><strong>FIN DEBUG Mysql :</strong></span> '.$reqid;
return
$debug;
}


/*************************************************
PUBLIC : Renvoie le nombre de requète dans le tableau
(nb de requetes avec des noms différents)
**************************************************/
public function nb_req() {
return
count($this->tabreq);
}


/*************************************************
PUBLIC : renvoie l'état d'une requète :
- 0 : la requete de ce nom la n'existe pas
- 1 : la requète existe
- 2 : la requete existe, elle a été exécuté (un résultat sql)
**************************************************
reqid : nom de la requete
**************************************************/
PUBLIC function is_req($reqid = 'default') {
if (isset(
$this->tabreq[$reqid])) {
if (isset(
$this->tabreq[$reqid]['result_id'])) {
return
2;
}
else {
return
1;
}
}
else {
return
0;
}
}

}
// fin classe



RE: Classe Mysql - orditeck - 07-03-2007

L'aide pour ce script ce trouve à cette adresse :
http://www.jeuweb.org/board/showthread.php?tid=1312


RE: Classe Mysql - shadow_49 - 19-10-2008

Bonjour,

En cherchant un exemple de class pour les fonctions mysql, je suis tombé sur celle la, qui me plais plutot bien.

J'avais juste une petite amélioration à proposer, dans la fonction do_dynquery, le code suivant :

Code PHP :
<?php 
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);
}
}
=> le for pourrait être remplacé par un foreach (enfin cela ne change rien, mais c'est plus "simple" qu'un for si celui ci pacourt tout le tableau (ce n'est pas vraiment une amélioration c'est vrai, car cela n'enlève qu'une ligne de code ^^ )

J'aurai aussi voulu savoir si elle était sécurisée (protégée des injections html, sql, javascript, ou comment combler des protections manquantes dans mon code).

Merci d'avance pour la réponse !


RE: Classe Mysql - Raoull - 24-10-2008

shadow_49,
désolé de répondre si tard, je ne viens plus que rarement sur le net depuis le début de l'été et j'ai arreté pour l'instant tout développement web.

Pour répondre à ta question, j'utilise aussi habituellement un FOR EACH pour traiter les tableaux, mais pour le cas de la fonction "dynquery" j'ai utilisé un if ... parce que je n'ai pas su faire autrement : il fallait que je récupère les variables d'une requête (pour les traiter avec mysql_real_escape_string) puis les réaffecter chacune à leur bonne place dans le tableau. J'utilise donc un if pour connaitre l'emplacement (la variable $i) à lire et réaffecter.

Ya p-e une façon plus simple de faire, fort possible.

Pour ce qui est de la sécurité, il ya donc l'option "escape_string" qui passe toutes les STRINGs avec mysql_real_escape_string() qui protège les données lors d'un enregostrement SQL, et donc des injections SQL.

Pour ce qui est de la sécurité HTML ou JS, il faudra traiter tes chaines avec htmlspecialchars() et ses amis par exemple.


Je balance ici la dernière version perso de cette classe : (mes tabulations ne ressortent pas ici...)

Code PHP :
<?php
/**
* class.mysql.php
* @package
* @subpackage
* @link
* @author Brice C. Huelce <contact AT isoat DOT org>
* @version 0.15
* @date 07/07/2008 07:11:52
* @license http://opensource.org/licenses/gpl-3.0.html GNU Public License v3
* @copyright copyleft 2008 Isoat, Pork Team
* @link http://www.isoat.org
* @link http://konace.info
*
* v0.9, 23/11/2007 07:47:48
*
* v0.10, 02/05/2008 05:58:21
* - ajoute la fonction data_seek()
*
* v0.11, lundi 12 mai 2008
* - passage en utf8
*
* v0.12, 31/05/2008 05:42:31
* - REFONTE COMPLèTE !!!
* - renommage de la classe de "Mysql" en "is_mysql"
* - renommage du fichier de classe de "class.mysql.php" en "class.is_mysql.php"
*
* v0.13, 01/06/2008 08:00:52
* - mis un SPAN rouge sur les erreurs dans le debug
*
* v0.14, 14/06/2008 02:48:18
* - ajouter l'argument optionel $reqid à debug() pour n'avoir le debug que d'une seule requete
*
* v0.15, 07/07/2008 07:11:52
* - debug ne renvoie qu'une ligne si RAS
*/



/**
* Classe 'is_mysql'
* @package
* @subpackage
*/
class is_mysql {

// ### VARIABLES ###

/**
* adresse du serveur mysql
* @access private
* @var string
*/
private $host = '';

/**
* nom d'utilisateur du serveur mysql
* @access private
* @var string
*/
private $user = '';

/**
* mot de passe du serveur mysql
* @access private
* @var string
*/
private $pass = '';

/**
* nom de la base mysql utilisée
* @access private
* @var string
*/
private $base = '';

/**
* identifiant de la connexion
* @access private
* @var integer
*/
private $connect_id = 0;

/**
* tableau général des requêtes
* @access private
* @var array
*/
public $tabreq = array();

/**
* nb de requêtes effectuées
* @access public
* @var integer
*/
public $nb_req_sql = 0;

// ### PROCEDURES ###

/**
* Construction de l'objet
* @access public
* @param string $host adresse du serveur mysql
* @param string $user nom d'utilisateur du serveur mysql
* @param string $pass mot de passe du serveur mysql
* @param string $base nom de la base mysql utilisée
*/
public function __construct($host = 'localhost', $user = 'root', $pass = '', $base = '') {
$this->host = $host;
$this->user = $user;
$this->pass = $pass;
$this->base = $base;
}

/**
* destruction de l'objet (ferme la connexion)
* - mysql_close
* - musql_free_result
* @access public
*/
public function __destruct() {
//$this->del_allquery(TRUE); // libère la mémoire de toutes les requêtes
$this->close(); // ferme la connexion (si besoin)
}

// ### CONNEXION / DéCONNEXION ###

/**
* Renvoie l'état de la connexion
* @access public
* @return bool TRUE si connecté, FALSE sinon
*/
public function is_connect() {
if (
$this->connect_id)
return
TRUE;
return
FALSE;
}

/**
* connexion explicite, choix/ouverture d'une autre base
* @access public
* @param string $base nouvelle base à sélectionner (autre que celle précisé lors de la création de l'objet)
* @return bool TRUE si bien connecté, FALSE sinon
* @todo pas besoin de fermer/réouvrir la connexion pour changer de base
*/
public function connect($base = '') {
// changement de la base de données
if ($base != '' && $base != $this->base) {
$this->close();
$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('(1) Sélection impossible de la base de données : '.mysql_error());
}
else
// erreur lors de la connexion à la bdd
die('(2) Connexion impossible au serveur SQL : '.mysql_error());
}
else
return
TRUE; // déjà connecté
}

/**
* déconnexion explicite
* - mysql_close
* @access public
* @return bool TRUE si la déconnexion a bien eu lieu (ou si déjà déconnecté), FALSE sinon
*/
public function close() {
if (
$this->connect_id) { // on déconnecte
if (mysql_close($this->connect_id)) {
$this->connect_id = 0;
return
TRUE;
}
else
return
FALSE; // erreur lors de la déconnexion
}
else
return
TRUE; // on était pas connecté
}

// ### EXÉCUTION DES REQUêTES SIMPLES ###

/**
* créé une nouvelle requete dans le tableau
* @access private
* @param string $reqid nom de la requete
*/
private function initreq($reqid = 'default') {
if (isset(
$this->tabreq[$reqid]))
unset(
$this->tabreq[$reqid]);

$this->tabreq[$reqid] = array();
$this->tabreq[$reqid]['error'] = array();
}

/**
* Créé et exécute une requete
* @access public
* @param string $reqid nom de la requete
* @param string $query requete SQL
* @return mixed FALSE si erreur, sinon le résultat (ressource ou autre)
*/
public function query($reqid = 'default', $query = '') {
// (ré)initialise la requête dans le tableau
$this->initreq($reqid);

// initialise la nouvelle requête
$this->tabreq[$reqid]['query'] = $query;

// on execute la requete
return $this->do_query($reqid);
}

/**
* exécute une requete du tableau
* - mysql_query
* - mysql_insert_id (si INSERT)
* @access private
* @param string $reqid nom de la requete
* @return mixed FALSE si erreur, sinon le résultat (ressource ou autre)
*/
private function do_query($reqid = 'default') {
if (isset(
$this->tabreq[$reqid]['query'])) {
if (!
$this->connect_id) // on se connecte au besoin
$this->connect();

// 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++;

// -- 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();

// OK
return $this->tabreq[$reqid]['result_id'];
}
else {
// erreur, on la stocke dans 'error'
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> '.mysql_error();
return
FALSE;
}
}
else {
// requete n'existe pas
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> La requête "'.$reqid.'" n\'existe pas';
return
FALSE;
}
}

// ### GESTION/EXECUTION DES REQUETES DYNAMIQUES ###

/**
* exécute une requete dynamique
* @access public
* @param string $reqid nom de la requete
* @param string $dquery requete sql au fomat sprintf
* @param mixed $dvars string si 1 seule var, sinon array contenant la(es) variable(s) à inserer dans la requête
* @param bool $escape_string effetuer un mysql_real_escape_string sur les variables dynamiques string
* @return mixed FALSE en cas d'erreur, sinon le résultat (ressource ou autre)
*/
public function dynquery($reqid = 'default', $dquery = '', $dvars = NULL, $escape_string = 0) {
// (ré)initialise la requête dans le tableau
$this->initreq($reqid);

// --- stocke la requete dynamique
$this->tabreq[$reqid]['dynquery'] = $dquery;

// --- stocke les variables dynamiques
if (!is_null($dvars)) {
// initialise le tableau des vars dynamiques
$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;
}
}
else {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> $dvars est NULL';
return
FALSE;
}

// --- échappe les chaines de caratères
if ($escape_string == 1) {
// on se connecte au besoin
if (!$this->connect_id)
$this->connect();

// on échappe
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
return $this->do_query($reqid);
}

// ### GESTION DES REQUETES (DANS LE TABLEAU) ###

/**
* Supprime une requete du tableau de requete
* - mysql_free_result
* @access public
* @param string $reqid nom de la requete
* @param bool $free_result faire un mysql_free_result de chaque resultat mysql
* @return bool
*/
// public function del_query($reqid = 'default', $free_result = FALSE) {
// if (isset($this->tabreq[$reqid])) {
// if ($free_result && isset($this->tabreq[$reqid]['result_id']))
// @mysql_free_result($this->tabreq[$reqid]['result_id']);
//
// unset($this->tabreq[$reqid]);
// return TRUE;
// }
// else {
// $this->tabreq[$reqid]['error'][] = '['.__function__.'] La requête "'.$reqid.'" n\'existe pas';
// return FALSE; // la requete n'existait pas
// }
// }

/**
* Supprime toutes les requetes du tableau de requete
* (fait automatiquement par le destructeur)
* - mysql_free_result
* @access public
* @param bool $free_result faire un mysql_free_result de chaque resultat mysql
*/
// public function del_allquery($free_result = FALSE) {
// foreach($this->tabreq as $key => $value) {
// if ($free_result && isset($this->tabreq[$key]['result_id']))
// @mysql_free_result($this->tabreq[$key]['result_id']);
//
// unset($this->tabreq[$key]);
// }
// }

// ### GESTION DES RÉSULTATS ###

/**
* renvoie le contenu d'un champ depuis un résultat SQL
* - mysql_result
* @access public
* @param string $reqid nom interne de la requete
* @param int $rows Le numéro de la ligne à récupérer
* @param string $field Le nom ou la position du champ à récupérer
* @return mixed FALSE si erreur sinon le résultat
*/
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 {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> Pas de résultat trouvé ou bien la requête "'.$reqid.'" n\'existe pas';
return
FALSE;
}
}

/**
* Renvoie un tableau depuis un résultat SQL
* @access public
* @param string $reqid nom interne de la requete
* @param string $mode mode du tableau retourné : ASSOC, NUM ou BOTH
* @return mixed FALSE en cas d'erreur sinon un tableau
*/
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 {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> Pas de résultat trouvé ou bien la requête "'.$reqid.'" n\'existe pas';
return
FALSE;
}
}

/**
* Déplace le pointeur interne de résultat MySQL
* @access public
* @param int $row_number
* @return bool
*/
public function data_seek($reqid = 'default', $row_number = 0) {
if (isset(
$this->tabreq[$reqid]['result_id'])) {
$row_number = intval($row_number);
return @
mysql_data_seek($this->tabreq[$reqid]['result_id'], $row_number);
}
else {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> Pas de résultat trouvé ou bien la requête "'.$reqid.'" n\'existe pas';
return
FALSE;
}
}

/**
* renvoie le nombre d'enregistrement affecté depuis un résultat SQL
* - mysql_num_rows : select
* - mysql_affected_rows : insert, update, replace, delete
* @access public
* @param string $reqid nom de la requete
* @return mixed FALSE si erreur sinon INT
*/
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 {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> Pas de résultat trouvé ou bien la requête "'.$reqid.'" n\'existe pas';
return
FALSE;
}
}

/**
* renvoie l'id (auto-increment) généré par une requête, si INSERT
* @access public
* @param string $reqid nom de la requete
* @return mixed FALSE si erreur sinon INT
*/
public function insert_id($reqid = 'default') {
if (isset(
$this->tabreq[$reqid]['insert_id'])) {
return
$this->tabreq[$reqid]['insert_id'];
}
else {
$this->tabreq[$reqid]['error'][] = '<span style="color:#f00">['.__function__.']</span> La requête "'.$reqid.'" n\'existe pas ou bien pas de insert_id()';
return
FALSE;
}
}

// ### DIVERS ###

/**
* renvoie l'état d'une requête
* @access public
* @param string $reqid nom de la requete
* @return int 0 : pas de requete de ce nom, 1 : la requête existe, 2 : la requete existe + un résultat
*/
// public function is_req($reqid = 'default') {
// if (isset($this->tabreq[$reqid])) {
// if (isset($this->tabreq[$reqid]['result_id']))
// return 2;
//
// return 1;
// }
// return 0;
// }

/**
* Renvoie le nombre de requête dans le tableau
* @access public
* @return int
*/
// public function nb_req() {
// return count($this->tabreq);
// }

// ### DEBUG ###

/**
* Renvoie le journal des erreurs survenues, pour debug
* @access public
* @param bool $mode_echo TRUE : affiche direct le debug au lieu de renvoyer dans une string
* @return mixed Renvoie une STRING ou bien TRUE en mode_echo
*/
public function debug($mode_echo = FALSE, $reqid = '') {
if (
count($this->tabreq) >0 ) {
$ret = '<pre>'."\n".'<strong>DEBUG ['.__CLASS__.']</strong>'."\n";
if (
$reqid == '')
$ret .= print_r($this->tabreq, TRUE);
else
$ret .= print_r($this->tabreq[$reqid], TRUE);
$ret .= "\n".'<strong>FIN DEBUG ['.__CLASS__.']</strong>'."\n".'</pre>';

if (
$mode_echo) { // affichage direct
echo $ret;
return
TRUE;
}
else
// retourne la string
return $ret;
}
else {
$ret = '<br />DEBUG ['.__CLASS__.'] : RAS';
if (
$mode_echo) { // affichage direct
echo $ret;
return
TRUE;
}
else
// retourne la string
return $ret;
}
}
}
?>