Bonjour à tous,
Dans le cadre d'une future application web que je souhaite développer, j'ai créer une classe d'accès à la base de données par l'intermédiaire de PDO.
J'aimerais avoir votre avis sur cette classe, sur sa pertinence, son utilité, si vous êtes arrivé à l'utiliser facilement, ... N'hésitez surtout pas à critiquer !
J'ai mis à la fin des exemples d'utilisation.
Merci d'avance à tous pour vos réponses !
Pour info voici ma config : PHP 5.2.4 avec le driver pdo_mysql 5.0.18 et MySQL 5.0.27.
Dans le cadre d'une future application web que je souhaite développer, j'ai créer une classe d'accès à la base de données par l'intermédiaire de PDO.
J'aimerais avoir votre avis sur cette classe, sur sa pertinence, son utilité, si vous êtes arrivé à l'utiliser facilement, ... N'hésitez surtout pas à critiquer !
J'ai mis à la fin des exemples d'utilisation.
Merci d'avance à tous pour vos réponses !
Pour info voici ma config : PHP 5.2.4 avec le driver pdo_mysql 5.0.18 et MySQL 5.0.27.
<?php
class Connexion {
private static $host = "localhost"; // votre serveur web
private static $bdd = "bdd"; // le nom de la BDD
private static $user = "user"; // l'utilisateur de la BDD
private static $password = "password"; // le mot de passe de l'utilisateur de la BDD
private $unPDO; // instance de l'objet PDO
private $stmt; // instance de l'objet PDOStatement
private $sql; // stocke le SQL
private $procedure; // nom de la prodédure stockée
private $param = array(); // paramètres de la procédure stockée
private $transactionEnCours; // permet de gérer les transactions SQL
// Création d'un nouvel objet Connexion
public function __construct(){
try{
$this->unPDO = new PDO("mysql:host=".self::$host.";dbname=".self::$bdd, self::$user, self::$password, PDO::getAvailableDrivers());
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Requête SQL sur la BDD
public function requeteSQL($sql){
try{
$this->sql = $sql;
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Procédure stockée sur la BDD
public function requeteProcedure($procedure){
try{
$this->sql = "";
$this->procedure = $procedure;
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Ajouter des paramètres à une procédure stockée
// Soit Array soit chaine de caractère
public function parametreAjouter($param){
try{
if(is_array($param)){
$this->param = $param;
} else {
$this->param[] = $param;
}
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Exécuter le SQL avec retour : requête ou procédure stockée
// paramètre $retourTableauAssociatif : permet de forcer le retour de fonction en tableau associatif
public function executer($retourTableauAssociatif = false){
try{
if($this->sql == ""){
$this->sql = "call ".$this->procedure;
$this->sql .= "(";
$indexParam = 0;
foreach ($this->param as $key=>$value){
if($indexParam != 0){
$this->sql .= ",";
}
$this->sql .= ":".$key;
$indexParam++;
}
$this->sql .= ")";
$this->stmt = $this->unPDO->prepare($this->sql, $this->unPDO->getAvailableDrivers());
foreach($this->param as $key=>$valeur){
$type = $this->retournerType($valeur);
$this->stmt->bindValue(":".$key, $valeur, $type);
}
$this->stmt->execute();
} else {
$this->stmt = $this->unPDO->prepare($this->sql);
$this->stmt->execute();
}
$error = $this->stmt->errorInfo();
if(isset($error[2])){
$error = $this->stmt->errorInfo();
throw new Exception($error[2]);
}
$i = 0;
$lignes = array();
while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) {
$lignes[$i] = $row;
$i++;
}
if($retourTableauAssociatif){
return $lignes[0];
} else {
return $lignes;
}
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Exécuter le SQL sans retour : requête ou procédure stockée
public function executerSansRetour(){
try{
if($this->sql == ""){
$this->sql = "call ".$this->procedure;
$this->sql .= "(";
$indexParam = 0;
foreach ($this->param as $key=>$value){
if($indexParam != 0){
$this->sql .= ",";
}
$this->sql .= ":".$key;
$indexParam++;
}
$this->sql .= ")";
$this->stmt = $this->unPDO->prepare($this->sql, $this->unPDO->getAvailableDrivers());
foreach($this->param as $key=>$valeur){
$type = $this->retournerType($valeur);
$this->stmt->bindValue(":".$key, $valeur, $type);
}
$this->stmt->execute();
} else {
$this->stmt = $this->unPDO->prepare($this->sql);
$this->stmt->execute();
}
$error = $this->stmt->errorInfo();
if(isset($error[2])){
$error = $this->stmt->errorInfo();
throw new Exception($error[2]);
}
} catch (Exception $erreur) {
throw new Exception($erreur->getMessage());
}
}
// Compte le nombre de ligne affectée par un requête SELECT, INSERT, UPDATE, DELETE
public function nombreLigne(){
try{
if($this->stmt instanceof PDOStatement){
return $this->stmt->rowCount();
} else {
throw new Exception("L'objet PDOStatement n'a pas été instancié.");
}
} catch (Exception $erreur){
throw new Exception($erreur->getMessage());
}
}
// Compte le nombre de colonne
public function nombreColonne(){
try{
return $this->stmt->columnCount();
} catch (Exception $erreur){
throw new Exception($erreur->getMessage());
}
}
// Retrourne le dernier ID insérer sur la BDD : pour fonctionner le moteur de stockage la table doit être en InnoDB
public function dernierID(){
$lastID = $this->unPDO->lastInsertId();
if($lastID == 0){
throw new Exception("Dernier ID insérer à 0");
} else {
return $lastID;
}
}
// Dans le cas d'une requête avec plusieurs SELECT, permet de se positionner le SELECT suivant
// NON FONCTIONNEL AVEC MYSQL : PDOStatement::nextRowset() => ne fonctionne pas avec MySQL
public function selectSuivant(){
$this->stmt->nextRowset();
$i = 0;
$lignes = array();
while ($row = $this->stmt->fetch(PDO::FETCH_NAMED)) {
$lignes[$i] = $row;
$i++;
}
return $lignes;
}
// Permet de démarrer une transaction : pour fonctionner le moteur de stockage la table doit être en InnoDB
public function transactionDemarrer(){
$this->transactionEnCours = true;
$this->unPDO->beginTransaction();
}
// Permet de confirmer une transaction : pour fonctionner le moteur de stockage la table doit être en InnoDB
public function transactionConfirmer(){
$this->transactionEnCours = false;
$this->unPDO->commit();
}
// Permet d'annuler une transaction : pour fonctionner le moteur de stockage la table doit être en InnoDB
public function transactionAnnuler(){
if($this->transactionEnCours){
$this->unPDO->rollBack();
}
$this->transactionEnCours = false;
}
// Clotûre la connexion avec la BDD
public function deconnexion(){
$this->unPDO = null;
}
// Retourne le SQL éxécuter dans la BDD
public function debug(){
throw new Exception($this);
}
// Est exécuté lorsque l'instance de l'objet Connexion() est détruit
public function __destruct(){
if($this->transactionEnCours) $this->unPDO->transactionAnnuler();
if($this->unPDO != null) $this->unPDO = null;
}
// Est exécuté lorsque l'instance de l'objet Connexion() est converti en String
public function __toString() {
return $this->sql;
}
// Retourne le type du paramétre pour une prodédure stockée
private function retournerType($variable){
switch ($variable) {
case is_int($variable) :
return PDO: [langue]ARAM_INT;
break;
case is_string($variable) :
return PDO: [langue]ARAM_STR;
break;
case is_bool($variable) :
return PDO: [langue]ARAM_BOOL;
break;
case is_null($variable) :
return PDO: [langue]ARAM_NULL;
break;
default:
throw new Exception("Ce type de données n'est pas géré !");
break;
}
}
}
// Utilisation
// Exemple 1 : requête SQL
$uneConnexion = new Connexion();
$uneConnexion->requeteSQL("SELECT * FROM ma_table");
$desResultat = $uneConnexion->executer();
// La variable $desResultat contient l'ensemble des données de la table 'ma_table'
$uneConnexion->deconnexion();
// Exemple 2 : procédures stockées avec transaction
try{
$uneConnexion = new Connexion();
$uneConnexion->transactionDemarrer();
$uneConnexion->requeteProcedure("update_table1");
$uneConnexion->parametreAjouter("param1");
$uneConnexion->parametreAjouter("param2");
$uneConnexion->executerSansRetour();
$uneConnexion->requeteProcedure("update_table2");
$desParam = array("param1", "param2", "param3");
$uneConnexion->parametreAjouter($desParam);
$uneConnexion->executerSansRetour();
// Traitement
// Si une erreur intervient dans le traitement, la transaction est annulée dans le catch
// Si aucune erreur n'est soulevé, la transaction est confirmée
$uneConnexion->transactionConfirmer();
$uneConnexion->deconnexion();
} catch(Exception $erreur){
$uneConnexion->transactionAnnuler();
$uneConnexion->deconnexion();
echo($erreur->getMessage());
}
?>