8797 sujets

Développement web côté serveur, CMS

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.


<?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());
	}
?>