24-10-2008, 11:52 PM
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...)
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;
}
}
}
?>