* @copyright Copyright (c) 2013, Tela Botanica (accueil@tela-botanica.org) * @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL * @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL */ class Bdd2 extends PDO { const SQL_MODE_ASSOC = PDO::FETCH_ASSOC; const SQL_MODE_OBJET = PDO::FETCH_OBJ; const SQL_RETOUR_COMPLET = 'All'; const SQL_RETOUR_LIGNE = 'Row'; const SQL_RETOUR_COLONNE = 'Column'; const SQL_RETOUR_BRUT = 'Raw'; function __construct($config, $base = 'database_cel') { $cfg = $config[$base]; // ATTENTION : la connexin à la bdd peut échouer si l'host vaut localhost. Utiliser 127.0.0.1 à la place. $dsn = $cfg['phptype'].':dbname='.$cfg['database'].';host='.$cfg['hostspec']; try { // Création de la connexion en UTF-8 à la BDD parent::__construct($dsn, $cfg['username'], $cfg['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); // Affiche les erreurs détectées par PDO (sinon mode silencieux => aucune erreur affiché) parent::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo 'La connexion à la base de donnée via PDO a échouée : ' .$dsn . "\n". $e->getMessage(); } } /** * Protège automatiquement toutes les chaines comprises entre deux caractères '|'. * Puis execute la requete. * @see protegerRequete() * @param unknown_type $requete */ public function requeter($requete, $retour = self::SQL_RETOUR_COMPLET, $mode = PDO::FETCH_ASSOC) { $requete = $this->protegerRequete($requete); return $this->executerRequete($requete, $retour, $mode); } /** * Protège automatiquement toutes les chaines comprises entre deux caractères '|'. * @see protegerRequete() * @param unknown_type $requete */ public function executer($requete) { $requete = $this->protegerRequete($requete); return $this->executerRequeteSimple($requete); } /** * Méthode permettant de rechercher dans une requete SQL sous forme de chaine (String) les chaines * à protéger. Cela évite de protéger chaque variable avant de l'insérer dans une requete SQL. * Par contre, il est important que les chaine à protéger ne contiennent pas le caractère '|'. * * @param $requete */ public function protegerRequete($requete) { if (substr_count($requete, '|') % 2 === 0) { if (preg_match_all('/\|([^|]*)\|/', $requete, $correspondances, PREG_SET_ORDER)) { foreach ($correspondances as $chaine) { $chaine_protegee = $this->quote($chaine[1]); $requete = str_replace($chaine[0], $chaine_protegee, $requete); } } } else { $this->messages[] = "La requête a protéger contient un nombre impair de caractère de protection '|'."; $requete = false; } return $requete; } public function proteger($chaine) { return $this->quote($chaine); } public function protegerTableau(Array $tableau) { foreach ($tableau as $id => $val) { if (is_array($val)) { $tableau[$id] = $this->protegerTableau($val); } else { $tableau[$id] = $this->proteger($val); } } return $tableau; } public function executerRequeteSimple($requete) { $resultat = false; try { $resultat = $this->exec($requete); if ($resultat === false) { $this->debug[] = "La requête a échoué : $requete"; } } catch (PDOException $e) { $message = "Fichier : {$e->getFile()} \nLigne : {$e->getLine()} \nMessage : {$e->getMessage()} \nRequête : $requete"; $code = E_USER_ERROR; throw new Exception($message, $code); } return $resultat; } public function executerRequete($requete, $retour = self::SQL_RETOUR_COMPLET, $mode = PDO::FETCH_ASSOC) { $resultat = false; try { switch ($retour) { case self::SQL_RETOUR_COMPLET : $resultat = $this->query($requete)->fetchAll($mode);// Retourne toutes les lignes break; case self::SQL_RETOUR_LIGNE : $resultat = $this->query($requete)->fetch($mode);// Retourne la première ligne break; case self::SQL_RETOUR_COLONNE : $resultat = $this->query($requete)->fetchColumn();// Retourne la première colonne de la première ligne break; case self::SQL_RETOUR_BRUT : $resultat = $this->query($requete);// Retourne l'objet brut pour être utilisé dans une boucle de type foreach break; default: $this->debug[] = "Le type de retour '$retour' est inconnu."; } if ($resultat === false) { $this->debug[] = "La requête a retourné aucun résultat : $requete"; } } catch (PDOException $e) { $this->debug[] = sprintf($this->getTxt('sql_erreur_requete'), $e->getFile(), $e->getLine(), $e->getMessage(), $requete); } return $resultat; } public function getTxt($id) { $sortie = ''; switch ($id) { case 'sql_erreur' : $sortie = 'Requête echec. Fichier : "%s". Ligne : "%s". Message : %s'; break; case 'sql_erreur_requete' : $sortie = "Requête echec.\nFichier : %s.\nLigne : %s.\nMessage : %s.\nRequête : %s"; break; default : $sortie = $id; } return $sortie; } public function obtenirDernierId() { return $this->lastInsertId(); } }