Abstraction pdo

4/5 (47 avis)

Vue 6 620 fois - Téléchargée 346 fois

Description

Bonjour,
Cette classe permet d'étendre le module PDO.
La classe PdoManager ouvre la connexion en fonction de l'adapter passé.
Toutes les méthodes de PDO sont accessibles via la classe PdoManager grace a la fonction __call

Ex : appel de la méthode query
$oPdo = new DaoFactory::factory($aParams);
$oPdo->query('SELECT tata_yoyo FROM chapeau');

L'avantage est d'avoir des nom de méthode standardisé pour récupérer par exemple la liste des tables, la description des tables. Dans les classes PdoMysql et PdoPgsl on peut facilement ajouter des méthodes qui demandes des syntaxes SQL différentes selon les SGBD
Pour rajouter le support d'autre bdd il suffit par exemple de créer une class PdoMssql et d'y implémenter les méthodes obligatoires.
Voila c'est pas une classe très compliqué mais elle me sert beaucoup.
J'attend vaut critique et idées d'amélioration

Source / Exemple :


<?php
/**

  • @abstract
  • @name PdoManager
  • @author aberthelot
  • @since 11/10/2008
  • @package Dao::Pdo
  • @version 4.0.0 - AXB - 11/10/2008
  • @version 4.0.1 - AXB - 14/11/2008 - Déportation de la méthode connect dans les classes filles
  • /
abstract class PdoManager { /**
  • Host de connexion
*
  • @access protected
  • @var string
  • /
protected $_sHostname; /**
  • Nom d'utilisateur
*
  • @access protected
  • @var string
  • /
protected $_sUsername; /**
  • Password de connexion
*
  • @access protected
  • @var string
  • /
protected $_sPassword; /**
  • Adapter connexion
  • Ex : mysql, pgsql
  • @access protected
  • @var string
  • /
protected $_sAdapter; /**
  • Nom de la base de données
*
  • @access protected
  • @var string
  • /
protected $_sBasename; /**
  • Port de connexion
*
  • @access protected
  • @var integer
  • /
protected $_iPort; /**
  • Encodage de la base de données
*
  • @access protected
  • @var string
  • /
protected $_sEncoding; /**
  • Connexion base de données
*
  • @access protected
  • @var object
  • /
protected $_oPdoInstance = null; /**
  • Constructeur de la classe
  • Initialise les variables de connexion
  • Test si l'extension pdo est chargée
*
  • @param array $aParams
  • @return void
  • /
public function __construct($aParams) { $this->_sAdapter = ( isset($aParams['adapter']) ) ? $aParams['adapter'] : null; $this->_sHostname = ( isset($aParams['hostname']) ) ? $aParams['hostname'] : null; $this->_sPassword = ( isset($aParams['password']) ) ? $aParams['password'] : null; $this->_sUsername = ( isset($aParams['username']) ) ? $aParams['username'] : null; $this->_sBasename = ( isset($aParams['basename']) ) ? $aParams['basename'] : null; $this->_iPort = ( isset($aParams['port']) ) ? $aParams['port'] : null; $this->_sEncoding = ( isset($aParams['encoding']) ) ? $aParams['encoding'] : null; if( false === $this->checkExtensionPDo() ) { throw new Exception('L\'extension "pdo" ou "pdo_'.$this->_sAdapter.'" ne sont pas activées.', E_ERROR); } } /**
  • Connexion à la base de données
  • Passe la gestion des erreurs en exception
  • Si mysql on active l'émulation des requêtes préparés
  • Initialisation de l'encodage de la connexion
*
  • @access public
  • @return void
  • /
public function connect() { if( is_null($this->_oPdoInstance) ) { $this->_oPdoInstance = new PDO($this->_getDsn(), $this->_sUsername, $this->_sPassword); $this->_oPdoInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); if( $this->_oPdoInstance->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql' ) { $this->_oPdoInstance->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); } $this->_setConnectionEncoding(); } } /**
  • Mapping des fonction PDO
*
  • @access public
  • @param string $sMethod
  • @param array $aArguments
  • @return mixed|boolean
  • /
public function __call($sMethod, $aArguments) { if( method_exists(get_class($this->_oPdoInstance), $sMethod) ) { return call_user_func_array(array($this->_oPdoInstance, $sMethod), $aArguments); } return false; } /**
  • Retourne la liste des drivers disponible
*
  • @static
  • @access public
  • @return array
  • /
public static function getAvailableDrivers() { return PDO::getAvailableDrivers(); } /**
  • Ferme la connexion à la base de données
*
  • @access public
  • @return void
  • /
public function close() { $this->_oPdoInstance = null; } /**
  • Test si l'extension pdo est activé
*
  • @access private
  • @return boolean
  • /
private function checkExtensionPDo() { if ( extension_loaded('pdo') ) { if( extension_loaded('pdo_'.$this->_sAdapter) ) { return true; } } return false; } /**
  • Retourne le driver de connexion
*
  • @abstract
  • @access protected
  • @return void
  • /
abstract protected function _getDsn(); /**
  • Modifie l'encodage de la connexion
*
  • @abstract
  • @access protected
  • @return void
  • /
abstract protected function _setConnectionEncoding(); /**
  • Retourne la description de la table
*
  • @abstract
  • @access public
  • @param string $sNameTable
  • @param string $sSchema
  • @return array
  • /
abstract public function describe($sNameTable, $sSchema = null); /**
  • Retourne la liste des tables de la base
*
  • @abstract
  • @access public
  • @return array
  • /
abstract public function listTable(); } ?> <?php /**
  • @name PdoMysql
  • @author aberthelot
  • @since 11/10/2008
  • @package Dao::Pdo
  • @version 4.0.0 - AXB - 11/10/2008
  • /
class PdoMysql extends PdoManager { /**
  • Constructeur de la classe
  • Initialise les variables de connexion
  • Test si l'extension pdo est chargée
*
  • @param array $aParams
  • @return void
  • /
public function __construct($aParams) { parent::__construct($aParams); } /**
  • Retourne la description de la table
*
  • @access public
  • @param string $sNameTable
  • @param string $sSchema
  • @return array
  • /
public function describe($sNameTable, $sSchema = null) { $aData = array(); $sSql = 'SHOW COLUMNS FROM '.$sNameTable.';'; $aRes = $this->query($sSql); $aRows = $aRes->fetchAll(); foreach($aRows as $iKey => $sValue) { $aData[$sValue['Field']]['name'] = $sValue['Field']; $aData[$sValue['Field']]['type'] = $sValue['Type']; $aData[$sValue['Field']]['null'] = ($sValue['Null'] == 'YES') ? true : false; $aData[$sValue['Field']]['key'] = ($sValue['Key'] == 'PRI') ? true : false; $aData[$sValue['Field']]['default'] = $sValue['Default']; $aData[$sValue['Field']]['extra'] = $sValue['Extra']; } return $aData; } /**
  • Retourne la liste des tables de la base
*
  • @access public
  • @return array
  • /
public function listTable() { $aData = array(); $sSql = 'SHOW TABLES;'; $aRes = $this->query($sSql); $aRows = $aRes->fetchAll(); foreach($aRows as $iKey => $sValue) { $aData[$iKey] = $sValue['Tables_in_'.$this->_sBasename]; } return $aData; } /**
  • Retourne le driver de connexion
*
  • @abstract
  • @access protected
  • @return void
  • /
protected function _getDsn() { return 'mysql:host='.$this->_sHostname.';dbname='.$this->_sBasename; } /**
  • Modifie l'encodage de la connexion
*
  • @access protected
  • @return void
  • /
protected function _setConnectionEncoding() { if(! is_null($this->_sEncoding) ) { $sStmt = $this->_oPdoInstance->prepare('SET CHARACTER SET ?'); $this->execute(array($this->_sEncoding)); } } } ?> <?php /**
  • @name PdoPgsql
  • @author aberthelot
  • @since 11/10/2008
  • @package Dao::Pdo
  • @version 4.0.0 - AXB - 11/10/2008
  • /
class PdoPgsql extends PdoManager { /**
  • Constructeur de la classe
  • Initialise les variables de connexion
  • Test si l'extension pdo est chargée
*
  • @param array $aParams
  • @return void
  • /
public function __construct($aParams) { parent::__construct($aParams); } /**
  • Retourne la description de la table
*
  • @access public
  • @param string $sNameTable
  • @param string $sSchema
  • @return array
  • /
public function describe($sNameTable, $sSchema = null) { $aData = array(); $sSql = "SELECT a.attnum, n.nspname, c.relname, a.attname AS colname, t.typname AS type, a.atttypmod, "; $sSql .= "FORMAT_TYPE(a.atttypid, a.atttypmod) AS complete_type, d.adsrc AS default_value, "; $sSql .= "a.attnotnull AS notnull, a.attlen AS length, co.contype, ARRAY_TO_STRING(co.conkey, ',') AS conkey "; $sSql .= "FROM pg_attribute AS a "; $sSql .= "JOIN pg_class AS c ON a.attrelid = c.oid "; $sSql .= "JOIN pg_namespace AS n ON c.relnamespace = n.oid "; $sSql .= "JOIN pg_type AS t ON a.atttypid = t.oid "; $sSql .= "LEFT OUTER JOIN pg_constraint AS co ON (co.conrelid = c.oid "; $sSql .= "AND a.attnum = ANY(co.conkey) AND co.contype = 'p') "; $sSql .= "LEFT OUTER JOIN pg_attrdef AS d ON d.adrelid = c.oid AND d.adnum = a.attnum "; $sSql .= "WHERE a.attnum > 0 AND c.relname = '".$sNameTable."' "; $sSql .= ( is_null($sSchema) ) ? '' : " AND n.nspname = '".$sSchema."' "; $sSql .= "ORDER BY a.attnum;"; $aRes = $this->query($sSql); $aRows = $aRes->fetchAll(); foreach($aRows as $iKey => $sValue) { $aData[$sValue['colname']]['name'] = $sValue['colname']; $aData[$sValue['colname']]['type'] = $sValue['complete_type']; $aData[$sValue['colname']]['null'] = ($sValue['notnull'] == 1) ? true : false; $aData[$sValue['colname']]['key'] = ($sValue['contype'] == 'P') ? true : false; $aData[$sValue['colname']]['default'] = $sValue['default_value']; } return $aData; } /**
  • Retourne la liste des tables de la base
*
  • @access public
  • @return array
  • /
public function listTable() { $aData = array(); $sSql = "SELECT c.relname AS table_name "; $sSql .= "FROM pg_class c, pg_user u "; $sSql .= "WHERE c.relowner = u.usesysid AND c.relkind = 'r' "; $sSql .= "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) "; $sSql .= "AND c.relname !~ '^(pg_|sql_)' "; $sSql .= "UNION "; $sSql .= "SELECT c.relname AS table_name "; $sSql .= "FROM pg_class c "; $sSql .= "WHERE c.relkind = 'r' "; $sSql .= "AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) "; $sSql .= "AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) "; $sSql .= "AND c.relname !~ '^pg_';"; $aRes = $this->query($sSql); $aRows = $aRes->fetchAll(); foreach($aRows as $iKey => $sValue) { $aData[$iKey] = $sValue['table_name']; } return $aData; } /**
  • Retourne le driver de connexion
*
  • @abstract
  • @access protected
  • @return void
  • /
protected function _getDsn() { return 'pgsql:host='.$this->_sHostname.';dbname='.$this->_sBasename; } /**
  • Modifie l'encodage de la connexion
*
  • @access protected
  • @return void
  • /
protected function _setConnectionEncoding() { if(! is_null($this->_sEncoding) ) { $stmt = $this->_oPdoInstance->prepare('SET client_encoding TO ?'); $this->execute(array($this->_sEncoding)); } } } ?> <?php namespace Dao; /**
  • @name DaoFactory
  • @author aberthelot
  • @since 11/10/2008
  • @package Dao
  • @version 4.0.0 - AXB - 11/10/2008
  • /
class DaoFactory { /**
  • Factory
  • Retourne une instance de la classe désigné par $sType
*
  • @param array $aParams
  • @return object
  • /
public static function factory(array $aParams) { if( isset($aParams['adapter']) ) { $sClass = 'Pdo'.ucfirst(strtolower($aParams['adapter'])); $oReflection = new ReflectionClass($sClass); if(! $oReflection->isSubclassOf('PdoManager') ) { throw new InvalidArgumentException($sClass.' n\'est pas une classe enfant de "PdoManager".', E_ERROR); } $oInstance = new $sClass($aParams); return $oInstance; } else { throw new Exception('Aucun type de base de données spécifié.', E_ERROR); } } } ?> ##### EXEMPLES ##### <?php $oPdo = new DaoFactory::factory($aParams); $sStmt = $oPdo->query('SELECT tata_yoyo FROM chapeau'); $aRes = $sStmt->fetchAll(); print '<pre>'; print_r($aRes); print '</pre>'; ?>

Codes Sources

A voir également

Ajouter un commentaire Commentaires
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
4 janv. 2009 à 12:54
Bravo c'est une jolie source. C'est propre, bien codé et bien documenté ;)
neigedhiver Messages postés 2480 Date d'inscription jeudi 30 novembre 2006 Statut Membre Dernière intervention 14 janvier 2011 18
4 janv. 2009 à 13:45
Salut,

Tu devrais préciser que la version de PHP requise est 5.3, parce que sinon, y'en a pas mal qui vont pas comprendre les messages d'erreurs alors qu'ils sont avec la dernière version stable ;)
C'est la première source que je vois qui nécessite PHP5.3 : ça fait plaisir, mais ça pourrait être intéressant de faire fonctionner ça sur PHP 5.2.x

J'ai pas regardé le code en détail (comme toujours... désolé... :/ ) mais avoir un commentaire comme ça de la part de WebDeb, c'est une belle performance. Donc rien que pour ça, chapeau !

@WebDeb : euh je ne te critique pas, hein, c'est juste que comme tu es exigeant (et c'est une qualité pour moi), il est rare que tu laisses un commentaire qui laisse penser que la source est parfaite... D'où la performance...

Et bonne année tout ça tout ça *=/:-)
webdeb Messages postés 488 Date d'inscription samedi 5 avril 2003 Statut Membre Dernière intervention 31 mars 2009 4
4 janv. 2009 à 14:06
@NeigeDHiver : lol ! Effectivement en général j'ai plutôt tendance à critiquer assez fortement certaines sources que je vois passer mais quand il y'en a des bonnes qui sortent du lot, je prends beaucoup de plaisir à dire qu'elles sont bien faites et qu'elles méritent d'être saluées. Ici c'est le cas :)
cs_dorian91 Messages postés 41 Date d'inscription mardi 3 octobre 2006 Statut Membre Dernière intervention 15 mars 2009
4 janv. 2009 à 15:57
Oups désolé j'ai oublie de retirer les namespaces. La source est mise à jour.
Merci pour vos commentaire ça fait plaisir.
Je suis en train de faire une petite mise a jour pour pouvooir lancer une action sur certaine méthode de pdo
Par exemple logger des requetes.
Je met la source a jour des que c'est fini
linkinparkem Messages postés 5 Date d'inscription samedi 27 janvier 2007 Statut Membre Dernière intervention 1 février 2009
29 janv. 2009 à 21:35
Super Code !!

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.