begin process at 2012 05 27 21:37:50
  Trouver un code source :
 
dans
 
Accueil > 

Code

 > 

Class et Objet ( POO )

 > GÉRER LES ACCÈS À UNE BASE DE DONNÉES VIA UNE DAO

GÉRER LES ACCÈS À UNE BASE DE DONNÉES VIA UNE DAO


 Information sur la source

Note :
10 / 10 - par 1 personne
10,00 / 10

  • 1

  • 2

  • 3

  • 4

  • 5

  • 6

  • 7

  • 8

  • 9

  • 10
Catégorie :Class et Objet ( POO ) Classé sous :couche DAO, abstraction pdo, prepareStatement, log4php, namespace Niveau :Débutant Date de création :27/05/2010 Date de mise à jour :01/06/2010 23:49:36 Vu / téléchargé :3 181 / 246

Auteur : genetApt151

Ecrire un message privé
Commentaire sur cette source (8)
Ajouter un commentaire et/ou une note

 Description

Bonjour,

GenDao est une source permettant de gérer les accès à la base de données sans avoir besoin d'utiliser des requêtes sql. Les opérations les plus courantes tel que la sauvegarde, la suppression, la mise à jour de données en base sont accessibles via des méthodes pré-implémentées.

Les requêtes sql sont basées sur PDO et existent en version normal et version utilisant les prepareStatement. Pour les opérations du type insert, update, delete.
Notions utilisées :

- accès au base de données via PDO
- prepareStatement PDO
- fichier de log avec apache log4php (http://logging.apache.org/log4php/index.html)
- namespace
- autoload de classes


Soit une table Post avec comme champ : id, title, body, day_2, hour_2

Exemples d'opérations possibles :

$post = Post::getById(43); //obtenir le post d'id 43
$posts =  Post::getAll(); //récupérer tous les enregistrements de la table
  
prototype : public static function get($where = null, array $order = null, $desc = false, $limit = null)
                
$posts =  Post::get(null,null,null,4); //récupérer les 4 premiers enregistrements
$posts =  Post::get(null,null,null,array(3,7)); //récupérer les enregistrements compris entre 3 à 7 (clause sql LIMIT)
  
$posts =  Post::get(array("day_2"=>date(date("y/m/d"))),null ,null,4); //récuperer les 4 enregistrements posté aujourd'hui
                
$posts =  Post::get(null, array("day_2","hour_2","title"),true,4);//récupére r les 4 premiers posts triées par date : les plus récents en premier
  
$cpt = Post::count();//compte le nombre de post
                
/* manipuler les données */

$post = new Post();
$post->title = "tire du post";
$post->setTitle("titre du post");
$post->save(); //sauvegarde en base -> insert
$post->body = "un texte";
$post->save(); //sauvegarde en base -> update
  
$post->delete();//suppression de l'objet
Post::deleteById(43);//suppression du post d'id 43

Contenu de la source :

-SqlRequest.class.php qui implémente les requêtes sql.
-Dao.class.php qui implémente les méthodes pour manipuler les objets en bases.

Pour faciliter le débogage, j'ai utilisé les log du framework log4php. Le fichier de configuration des logs se situe dans le répertoire log4php/configurators/log4php.properties. Il est paramétré en mode production, c'est à dire que les erreurs déclenchées par des exceptions sont écrite dans un fichier de log (log/globalError/error.log).

améliorations possibles :
- ajout de classes d'exception genDaoException...

Source

  • <?php
  • namespace GenDao;
  • //require_once realpath(dirname(__FILE__)).'/../config/Logger.php';
  • //require_once realpath(dirname(__FILE__)).'/../util/Util.class.php';
  • //require_once realpath(dirname(__FILE__)).'/../dal/Dal.class.php';
  • //require_once realpath(dirname(__FILE__)).'/../dal/DalPeer.class.php';
  • require_once realpath(dirname(__FILE__)).'/../model_autoload.php';
  • /**
  • * Description of SqlRequest
  • *
  • * @author Guillaume Genet
  • */
  • class SqlRequest
  • {
  • /*________________________________________________________________________*/
  • /**
  • * Permet de récuperer les informations sur une table
  • * @param <string> $table
  • * @return <PDOStatement>
  • */
  • public static function showColumns($table)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = 'SHOW COLUMNS FROM '.$table;
  • $recordset = $conn->query($query);
  • if($recordset === false)
  • throw new \Exception("la table ".$table." n'existe pas");
  • else
  • return $recordset->fetchAll(\PDO::FETCH_ASSOC);
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Permet de tester si la table existe
  • * @param <string> $table
  • * @return <bool>
  • */
  • public static function existTable($table)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = 'DESC '.$table;
  • $recordset = $conn->query($query);
  • return ($recordset instanceof \PDOStatement);
  • }
  • /*________________________________________________________________________*/
  • /** */
  • /**
  • * Permet de tester si la colonne existe dans la table
  • * @param <string> $table le nom de la table
  • * @param <string> $field nom du champ
  • * @return <boolean>
  • */
  • public static function existColumns($table, $field)
  • {
  • Util::emptyException($table);
  • Util::emptyException($field);
  • $field = strtolower(trim($field));
  • $champTable = static::showColumns($table);
  • foreach ($champTable as $tableField)
  • {
  • if(strtolower(trim($tableField['Field'])) == $field) return true;
  • }
  • return false;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * permet de genérer la clause where/set
  • * @param array $clause tableau ex:array('ville'=>'clermont-ferrand','nom'=>'genet') --> ville = 'clermont-ferrand' and nom='genet'
  • * @param PDO $conn
  • * @return <string> la chaine sql
  • */
  • public static function clause(array $clause, PDO $conn = null)
  • {
  • Util::nullException($clause);
  • $query = "";
  • $and = 0;
  • if($conn === null)
  • $conn = DalPeer::getConnection();
  • foreach($clause as $element => $valeur)
  • {
  • $temp = "";
  • if($and === 1)
  • $temp .= " and ";
  • $temp .= $element."=";
  • if (is_numeric($valeur))
  • $temp .= $valeur;
  • else
  • $temp .= $conn->quote($valeur,\PDO::PARAM_STR); //rajoute les quotes et protège la requête sql en ajoutant les \
  • $and = 1;
  • $query .= $temp;
  • }
  • return $query;
  • }
  • /*________________________________________________________________________*/
  • protected static function getClauseWhere($where,$conn = null)
  • {
  • if(empty($where)) return "";
  • if($conn === null)
  • $conn = DalPeer::getConnection();
  • $query = "";
  • $query .= ' WHERE ';
  • if(is_array($where))
  • {
  • $query .= static::clause($where);
  • }
  • elseif(is_string($where))
  • {
  • $query .= $conn->quote($where,\PDO::PARAM_STR); //rajoute les quotes et protège la requête sql en ajoutant les \
  • }
  • else
  • throw new \Exception("La clause where doit être un string ou un tableau");
  • return $query;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Contruit la requete insert
  • * @param <string> $table le nom de la table
  • * @param array $elements
  • * @return <int> l'identifiant de la ligne insérée
  • */
  • public static function insert($table, array $elements)
  • {
  • Util::emptyException($table);
  • Util::emptyException($elements);
  • $conn = DalPeer::getConnection();
  • $keys = array_keys($elements);
  • $values = array_values($elements);
  • $query = "INSERT INTO " . $table . " (";
  • $query .= implode(', ',$keys);
  • $query .= ") values (";
  • $countValues = count($values);
  • for ($i = 0; $i < $countValues; $i++) //ajout des valeurs
  • {
  • if (is_numeric($values[$i]))
  • $query .= $values[$i];
  • else
  • $query .= $conn->quote($values[$i],\PDO::PARAM_STR); //pour protéger la requête sql
  • if ($i != count($values) - 1)
  • {
  • $query .= ", ";
  • }
  • }
  • $query .= " )";
  • $flag = $conn->exec($query);
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('insert: '.$query.' --> nbLigneInsert='.$flag);
  • if($flag === 1)
  • $flag = $conn->lastInsertId(); //on récupère l'id
  • else
  • if($flag === false)
  • throw new \Exception("erreur lors de la reqête insertion - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Contruit la requete insert en utilisant un prepareStatement
  • * @param <string> $table le nom de la table
  • * @param <array> $elements
  • * @return <int> l'identifiant de la ligne insérée
  • */
  • public static function insertPrepareStatement($table, array $elements)
  • {
  • Util::emptyException($table);
  • Util::emptyException($elements);
  • $conn = DalPeer::getConnection();
  • $fieldNames = array_keys($elements); //recupère le nom des champs
  • $query = 'INSERT INTO '.$table;
  • $fields = '( ' . implode(' ,', $fieldNames) . ' )';
  • $values = '(:' . implode(', :', $fieldNames) . ' )';
  • $query .= $fields.' VALUES '.$values;
  • $stmt = $conn->prepare($query);
  • $flag = $stmt->execute($elements);
  • $stmt->closeCursor();
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('insert: '.$query.' --> nbLigneInsert='.$flag);
  • if($flag === true)
  • $flag = $conn->lastInsertId(); //on récupère l'id
  • else
  • if($flag === false)
  • throw new \Exception("erreur lors de la reqête insertion - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Contruit la requete update
  • * @param <string> $table
  • * @param <array> $update
  • * @param <array|string> $where
  • * @return <int> le nombre de ligne modifiée
  • */
  • public static function update($table, array $update, $where)
  • {
  • Util::emptyException($table);
  • Util::emptyException($update);
  • Util::emptyException($where);
  • $conn = DalPeer::getConnection();
  • $query = 'UPDATE '.$table.' SET ';
  • $i=0;
  • foreach ($update as $key => $value)
  • {
  • $query .= $key.'='.$conn->quote($value,\PDO::PARAM_STR);
  • if ($i != count($update) - 1)
  • {
  • $query .= ", ";
  • }
  • $i++;
  • }
  • $query .= static::getClauseWhere($where);
  • $flag = $conn->exec($query);
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('update: '.$query.' --> nbLigneUpdate='.$flag);
  • if($flag === false)
  • throw new \Exception("erreur lors de la reqête update - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Contruit la requete update
  • * @param <string> $table
  • * @param <array> $update
  • * @param <array> $where
  • * @return <int> le nombre de ligne modifiée
  • */
  • public function updatePrepareStatement($table, array $update, array $where)
  • {
  • Util::emptyException($table);
  • Util::emptyException($update);
  • Util::emptyException($where);
  • $conn = DalPeer::getConnection();
  • $query = 'UPDATE '.$table.' SET ';
  • $updateKeys = array_keys($update);
  • $whereKeys = array_keys($where);
  • $countUpdate = count($updateKeys);
  • for($i = 0; $i < $countUpdate ; $i++) //construction de la première partie set titre=:titre, message=:message
  • {
  • $query.= $updateKeys[$i]." = :".$updateKeys[$i];
  • if($i != $countUpdate-1)
  • $query.=", ";
  • }
  • $query .= " WHERE ";
  • $countWhere = count($whereKeys);
  • for($i = 0; $i < $countWhere ; $i++)
  • {
  • $query.=$whereKeys[$i]." = :".$whereKeys[$i];
  • if($i != $countWhere-1)
  • $query .= " and ";
  • }
  • $args = array_merge($update, $where);//on fusionne les 2 tableaux pour le prepareStatement
  • $sth = $conn->prepare($query);
  • $flag = $sth->execute($args);
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('update: '.$query.' --> nbLigneUpdate='.$flag);
  • if($flag === false)
  • throw new \Exception("erreur lors de la reqête update - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Contruit la requete delete
  • * @param <string> $table nom de la table
  • * @param array|string $where
  • * @return <int> le nombre de ligne supprimée
  • */
  • public static function delete($table, $where = null)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = 'DELETE FROM '.$table;
  • $query .= static::getClauseWhere($where);
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • $flag = $conn->exec($query);
  • if($logger->isDebugEnabled())
  • $logger->debug('delete: '.$query." --> nbLigneDelete=".$flag);
  • if($flag === false)
  • throw new \Exception("erreur lors du delete de l'objet en base - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * construit la requete sql select
  • * @param <string> $table
  • * @param array $elements
  • * @param <array|string> $where
  • * @param <array> $order
  • * @param <bool> $desc
  • * @param <int|array> $limit
  • * @return <array<stdclass>> la liste des enregistrements
  • */
  • public static function select($table, array $elements = null, $where = null,array $order = null,$desc = null, $limit = null)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = "SELECT ";
  • if(empty($elements))
  • $query .= " * ";
  • else
  • $query .= implode(",", $elements);
  • $query .= " FROM " . $table;
  • $query .= static::getClauseWhere($where);
  • if(!empty($order))
  • {
  • $query .= " ORDER BY ";
  • $countOrder = count($order);
  • for ($i = 0; $i < $countOrder; $i++)
  • {
  • $query .= $order[$i];
  • if($desc !== null && $desc === true) $query .=" DESC ";
  • if ($i < count($order) - 1)
  • {
  • $query .= ", ";
  • }
  • }
  • }
  • if($limit !== null )
  • {
  • if(is_array($limit))
  • {
  • if(count($limit) === 2)
  • $query .= " LIMIT ".$limit[0].", ".$limit[1];
  • else
  • throw new \Exception("erreur: 2 arguments attendus pour LIMIT");
  • }
  • else
  • $query .= " LIMIT ".$limit;
  • }
  • $recordset = $conn->query($query);
  • $result = null;
  • if($recordset === false)
  • throw new \Exception("erreur lors de la reqête :".$query." - erreur:".Util::printPdoError($conn->errorInfo()));
  • else
  • {
  • $recordset->setFetchMode(\PDO::FETCH_OBJ);
  • $result = $recordset->fetchAll();
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('select: '.$query." --> result: ".Util::get_print_contents($result));
  • }
  • return $result;
  • }
  • /*______________________________________________________________________________________________________________________________*/
  • /**
  • * construit la requete sql select avec un prepareStatement
  • * @param <string> $table
  • * @param array $elements
  • * @param <array> $where
  • * @param <array> $order
  • * @param <bool> $desc
  • * @param <int|array> $limit
  • * @return <array<stdclass>> la liste des enregistrements
  • */
  • public function selectPrepareStatement($table, array $elements = null,array $where = null, array $order = null,$desc = null, $limit = null)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = "SELECT ";
  • if(empty($elements))
  • $query .= " * ";
  • else
  • {
  • $countInsert = count($elements);
  • for($i = 0; $i < $countInsert ; $i++) //construction de la première partie set titre=:titre, message=:message
  • {
  • $query.= $elements[$i];
  • if($i != $countInsert-1)
  • $query.=", ";
  • }
  • }
  • $query .= " FROM " . $table;
  • if(!empty($where))
  • {
  • $query .= " WHERE ";
  • $whereKeys = array_keys($where);
  • $countWhere = count($whereKeys);
  • for($i = 0; $i < $countWhere ; $i++)
  • {
  • $query.=$whereKeys[$i]." = :".$whereKeys[$i];
  • if($i != $countWhere-1)
  • $query .= " and ";
  • }
  • }
  • if(!empty($order))
  • {
  • $query .= " ORDER BY ";
  • $countOrder = count($order);
  • for ($i = 0; $i < $countOrder; $i++)
  • {
  • $query .= $order[$i];
  • if($desc !== null && $desc === true) $query .=" DESC ";
  • if ($i < count($order) - 1)
  • {
  • $query .= ", ";
  • }
  • }
  • }
  • if($limit !== null )
  • {
  • if(is_array($limit))
  • {
  • if(count($limit) === 2)
  • $query .= " LIMIT ".$limit[0].", ".$limit[1];
  • else
  • throw new \Exception("erreur: 2 arguments attendus pour LIMIT");
  • }
  • else
  • $query .= " LIMIT ".$limit;
  • }
  • $sth = $conn->prepare($query);
  • $flag = $sth->execute($where);
  • if($flag === false)
  • throw new \Exception("erreur lors de la reqête select : $query - erreur:".Util::printPdoError($sth->errorInfo()));
  • $sth->setFetchMode(\PDO::FETCH_OBJ);
  • $result = $sth->fetchAll();
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('select: '.$query." --> result: ".Util::get_print_contents($result));
  • return $result;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Execute une requete sql
  • * @param <type> $query
  • * @return <PDOStatement> recordset
  • */
  • public static function query($query)
  • {
  • Util::emptyException($query);
  • $conn = DalPeer::getConnection();
  • $recordset = $conn->query($query);
  • $result = null;
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('query_object: '.$query." --> result: ".Util::get_print_contents($result));
  • if($recordset === false)
  • throw new \Exception("erreur lors de l'execution de la reqête:".$query." - erreur:".Util::printPdoError($conn->errorInfo()));
  • return $recordset;
  • }
  • /*________________________________________________________________________*/
  • /* execute une requete sql et renvoi un tableau de tableau associatif*/
  • public static function query_assoc($query)
  • {
  • $recordset = static::query($query);
  • $recordset->setFetchMode(\PDO::FETCH_ASSOC);
  • $result = $recordset->fetchAll();
  • return $result;
  • }
  • /*________________________________________________________________________*/
  • /* execute une requete sql et renvoi un tableau d'objet*/
  • public static function query_object($query)
  • {
  • $recordset = static::query($query);
  • $recordset->setFetchMode(\PDO::FETCH_OBJ);
  • $result = $recordset->fetchAll();
  • return $result;
  • }
  • /*________________________________________________________________________*/
  • /* constuit la requete count */
  • public static function count($table,$where = null)
  • {
  • Util::emptyException($table);
  • $conn = DalPeer::getConnection();
  • $query = "SELECT COUNT(*) as total FROM ".$table;
  • $query .= static::getClauseWhere($where);
  • $recordset = $conn->query($query);
  • if($recordset !== false)
  • {
  • $result = $recordset->fetch(\PDO::FETCH_ASSOC);
  • return $result["total"];
  • }
  • else
  • if(!static::existTable($table)) //pour aider le debogage
  • throw new \Exception("la table ".$table." n'existe pas");
  • else
  • throw new \Exception("erreur lors de l'execution de la reqête count - erreur:".Util::printPdoError($conn->errorInfo()));
  • }
  • }
  • ?>
  • /****************** la DAO ********************/
  • <?php
  • namespace GenDao;
  • /**
  • * Description of Dao
  • *
  • * @author Guillaume Genet
  • */
  • require_once realpath(dirname(__FILE__)).'/../model_autoload.php';
  • class Dao
  • {
  • /** Correspond à la clé primaire de la base de données */
  • public static $ID = "id";
  • /** tableau associatif permettant de stocker les champs issus de la base de données*/
  • public $attributs = null;
  • /** le nom de la classe source*/
  • public $className = null;
  • public $isNewInstance = false;
  • public $isDeleted = false;
  • /*________________________________________________________________________*/
  • public static function getPrimaryKeyField()
  • {
  • return self::$ID;
  • }
  • /*________________________________________________________________________*/
  • protected function setAttributs(array $attributs)
  • {
  • $this->attributs = $attributs;
  • }
  • /*________________________________________________________________________*/
  • protected function initFields()
  • {
  • $champTable = SqlRequest::showColumns($this->className);
  • if($champTable != null)
  • {
  • //construction des attributs de la classe
  • if($this->attributs == null)
  • foreach ($champTable as $field)
  • {
  • $temp = strtolower($field['Field']);
  • $this->attributs[$temp] = null;
  • }
  • }
  • else
  • throw new \Exception($this->className." n'existe pas dans la base de données");
  • }
  • /*________________________________________________________________________*/
  • /** constructeur */
  • public function __construct($args=null)
  • {
  • //SqlRequest::query('SET NAMES utf8');
  • $this->attributs = array();
  • $this->className = get_called_class();
  • $this->isNewInstance = true;
  • $this->isDeleted = false;
  • $this->initFields();
  • }
  • /*________________________________________________________________________*/
  • public function isNew()
  • {
  • return $this->isNewInstance;
  • }
  • /*________________________________________________________________________*/
  • protected function setNewInstance($bool)
  • {
  • $this->isNewInstance = $bool;
  • }
  • /*________________________________________________________________________*/
  • public function isDeleted()
  • {
  • return $this->isDeleted;
  • }
  • /*________________________________________________________________________*/
  • protected function setDeleted($bool)
  • {
  • $this->isDeleted = $bool;
  • }
  • /*________________________________________________________________________*/
  • public function getClassName()
  • {
  • return $this->className;
  • }
  • /*________________________________________________________________________*/
  • /* constuit la requete count */
  • public static function count()
  • {
  • return SqlRequest::count(get_called_class());
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Permet de convertir un objet de type stdClass(PDO) en class courante
  • * @param stdClass $stdClass
  • * @return <Object>
  • */
  • public static function convertToClass(\stdClass $stdClass)
  • {
  • $class = get_called_class();
  • $dynamicClass = new $class; //nouvelle instance de classe
  • $dynamicClass->setNewInstance(false);
  • //convertion
  • foreach ($stdClass as $champ=>$valeur)
  • {
  • $dynamicClass->$champ = $valeur;
  • }
  • return $dynamicClass;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Permet de récuperer l'objet en fonction de l'identifiant
  • * @param <type> $id
  • * @return <Object> une instance de classe
  • */
  • public static function getById($id)
  • {
  • $result = SqlRequest::selectPrepareStatement(get_called_class(),null,array(self::$ID=>$id));
  • if(!empty($result))
  • {
  • $count = count($result);
  • if($count === 1)
  • return self::convertToClass($result[0]);
  • else
  • if($count > 1)
  • throw new \Exception("l'identifiant ".$id." est présent plusieurs fois dans la base de données");
  • }
  • return null;
  • }
  • /*________________________________________________________________________*/
  • /* fait un select * sur la table */
  • public static function getAll()
  • {
  • $stmt = SqlRequest::query("select * from ".get_called_class());
  • //$stmt->setFetchMode(\PDO::FETCH_CLASS,get_called_class(),null);
  • $stmt->setFetchMode(\PDO::FETCH_OBJ);
  • $result = $stmt->fetchAll();
  • foreach ($result as $line) //parcour des enregistrements
  • {
  • $listObjects[] = self::convertToClass($line);
  • }
  • $stmt -> closeCursor();
  • return $listObjects;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Permet de récuperer tous les objets en fonction des paramètres
  • * @param <array|string> $where la clause where de la requête
  • * @param <numeric|array> $limit le nombre d'enregistrement envoyé
  • * @param <array> $order un array contenant les champs de table, permet de trier les éléments
  • * @param <boolean> $desc vrai = tri décroissant, tri croissant sinon
  • * @return <array> un array contenant les objets
  • */
  • public static function get($where = null, array $order = null, $desc = false, $limit = null)
  • {
  • $listObjects = array();
  • $recordset = SqlRequest::selectPrepareStatement(get_called_class(),null,$where,$order,$desc,$limit);
  • foreach ($recordset as $line) //parcour des enregistrements
  • {
  • $listObjects[] = self::convertToClass($line);
  • }
  • return $listObjects;
  • }
  • /*________________________________________________________________________*/
  • /** Permet de sauvegarder l'objet */
  • public function save()
  • {
  • $newInstance = $this->isNew();
  • $dal = DalPeer::getConnection();
  • $flag = 0;
  • if($newInstance)//on fait un insert en base
  • {
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('doSave:insert');
  • $flag = SqlRequest::insert($this->className, $this->attributs);
  • if($flag >= 0)
  • {
  • $this->attributs[self::$ID] = $flag; //ajout de l'attribut id
  • $this->setNewInstance(false);
  • }
  • }
  • else //on fait un update en base
  • {
  • if(!$this->isDeleted())
  • {
  • $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
  • if($logger->isDebugEnabled())
  • $logger->debug('doSave:update');
  • $flag = SqlRequest::update($this->className, $this->attributs, array(self::$ID=>$this->attributs[self::$ID]));
  • }
  • else
  • throw new \Exception("erreur: impossible de sauvegarder des données préalablement supprimées");
  • }
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /** Permet de supprimer l'objet */
  • public static function deleteById($id)
  • {
  • $dal = DalPeer::getConnection();
  • $flag = SqlRequest::delete(get_called_class(),array(self::$ID => $id));
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /** Permet de supprimer l'objet */
  • public function delete()
  • {
  • $dal = DalPeer::getConnection();
  • $flag = 0;
  • if(!$this->isDeleted())
  • {
  • $flag = SqlRequest::delete($this->className,array(self::$ID => $this->attributs[self::$ID]));
  • $this->setDeleted(true);
  • }
  • else
  • throw new \Exception("erreur:appel de la fonction delete plusieurs fois à la suite");
  • return $flag;
  • }
  • /*________________________________________________________________________*/
  • /**
  • * Permet d'accéder aux attributs de la classe (sans l'utilisation d'un getter ex: echo $article->titre;)
  • * @param <string> $name le nom de l'attribut
  • * @return <array> le tableau de résultat
  • */
  • public function __get($name)
  • {
  • $name = strtolower($name);
  • if(array_key_exists($name, $this->attributs))
  • {
  • return $this->attributs[$name];
  • }
  • else
  • throw new \Exception( "l'attribut ".$name. " n'existe pas pour l'objet ".$this->className);
  • }
  • /*________________________________________________________________________*/
  • /** Permet d'accéder aux attributs de la classe (sans l'utilisation d'un setter ex: $article->titre='football')
  • * @param <string> $name le nom de l'attribut
  • * @param <object> $value
  • * @return <array> le tableau de résultat
  • */
  • public function __set($name, $value)
  • {
  • $name = strtolower($name);
  • if(array_key_exists($name, $this->attributs))//pour pas ajouter un element au tableau assosiatif
  • {
  • $this->attributs[$name] = $value;
  • }
  • else
  • throw new \Exception("l'attribut ".$name. " n'existe pas pour l'objet ".$this->className);
  • }
  • /*________________________________________________________________________*/
  • /** appel de méthode */
  • public function __call($name, $arguments)
  • {
  • $getterSetter = strtolower(substr($name, 0,3));
  • //pour accéder aux attributs en utilisant les getters
  • if($getterSetter === "get")
  • {
  • $attribut = strtolower(substr($name, 3));//nom de l'attribut
  • return $this->__get($attribut);
  • }
  • //pour affecter des attributs en utilisant les setters
  • else if($getterSetter === "set")
  • {
  • $attribut = strtolower(substr($name, 3));
  • $this->__set($attribut, $arguments[0]);
  • }
  • else
  • throw new \Exception($name." est une méthode inconnue");
  • }
  • }
  • ?>
<?php
namespace GenDao;

//require_once realpath(dirname(__FILE__)).'/../config/Logger.php';
//require_once realpath(dirname(__FILE__)).'/../util/Util.class.php';
//require_once realpath(dirname(__FILE__)).'/../dal/Dal.class.php';
//require_once realpath(dirname(__FILE__)).'/../dal/DalPeer.class.php';

require_once realpath(dirname(__FILE__)).'/../model_autoload.php';

/**
 * Description of SqlRequest
 *
 * @author Guillaume Genet
 */
class SqlRequest
{
    /*________________________________________________________________________*/
    /**
     * Permet de récuperer les informations sur une table
     * @param <string> $table
     * @return <PDOStatement>
     */
    public static function showColumns($table)
    {
        Util::emptyException($table);
        
        $conn = DalPeer::getConnection();

        $query = 'SHOW COLUMNS FROM '.$table;
	      $recordset = $conn->query($query);

	      if($recordset === false)
            throw new \Exception("la table ".$table." n'existe pas");
        else
            return $recordset->fetchAll(\PDO::FETCH_ASSOC);
    }

    /*________________________________________________________________________*/
     /**
      * Permet de tester si la table existe
      * @param <string> $table
      * @return <bool>
      */
    public static function existTable($table)
    {
        Util::emptyException($table);

        $conn = DalPeer::getConnection();
        $query = 'DESC '.$table;
	      $recordset = $conn->query($query);

	      return ($recordset instanceof  \PDOStatement);
    }

    /*________________________________________________________________________*/
    /** */
    /**
     * Permet de tester si la colonne existe dans la table
     * @param <string> $table le nom de la table
     * @param <string> $field nom du champ
     * @return <boolean>
     */
    public static function existColumns($table, $field)
    {
        Util::emptyException($table);
        Util::emptyException($field);

        $field = strtolower(trim($field));
	      $champTable = static::showColumns($table);

        foreach ($champTable as $tableField)
        {
            if(strtolower(trim($tableField['Field'])) == $field) return true;
        }
 
	      return false;
    }

    /*________________________________________________________________________*/
    /**
     * permet de genérer la clause where/set 
     * @param array $clause tableau ex:array('ville'=>'clermont-ferrand','nom'=>'genet') --> ville = 'clermont-ferrand' and nom='genet'
     * @param PDO $conn
     * @return <string> la chaine sql
     */
    public static function clause(array $clause, PDO $conn = null)
    {
        Util::nullException($clause);
        
      	$query = "";
      	$and = 0;
              
      	if($conn === null)
                  $conn = DalPeer::getConnection();
      
      	foreach($clause as $element => $valeur)
      	{
      	    $temp = "";
      	    if($and === 1)
      		$temp .= " and ";
      
      	    $temp .= $element."=";
      
      	    if (is_numeric($valeur))
      		$temp .= $valeur;
      	    else
      		$temp .= $conn->quote($valeur,\PDO::PARAM_STR); //rajoute les quotes et protège la requête sql en ajoutant les \
      
      	    $and = 1;
      	    $query .= $temp;
      	}
              
      	return $query;
    }

    /*________________________________________________________________________*/
    protected static function getClauseWhere($where,$conn = null)
    {
        if(empty($where)) return "";

        if($conn === null)
            $conn = DalPeer::getConnection();

        $query = "";
        $query .= ' WHERE ';

        if(is_array($where))
        {
            $query .= static::clause($where);
        }
        elseif(is_string($where))
        {
            $query .= $conn->quote($where,\PDO::PARAM_STR); //rajoute les quotes et protège la requête sql en ajoutant les \
        }
        else
            throw new \Exception("La clause where doit être un string ou un tableau");

        return $query;
    }

    /*________________________________________________________________________*/
    /**
     * Contruit la requete insert
     * @param <string> $table le nom de la table
     * @param array $elements
     * @return <int> l'identifiant de la ligne insérée
     */
    public static function insert($table, array $elements)
    {
        Util::emptyException($table);
        Util::emptyException($elements);
        
        $conn = DalPeer::getConnection();

	      $keys = array_keys($elements);
	      $values = array_values($elements);

	      $query = "INSERT INTO " . $table . " (";

        $query .= implode(', ',$keys);

        $query .= ") values (";
        $countValues = count($values);
	      for ($i = 0; $i < $countValues; $i++) //ajout des valeurs
	      {
	         if (is_numeric($values[$i]))
		          $query .= $values[$i];
	         else
		          $query .= $conn->quote($values[$i],\PDO::PARAM_STR); //pour protéger la requête sql
	     
           if ($i != count($values) - 1)
	         {
		          $query .= ", ";
	         }
	      }

	      $query .= " )";

        $flag = $conn->exec($query);

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('insert: '.$query.' --> nbLigneInsert='.$flag);

        if($flag === 1)
            $flag = $conn->lastInsertId(); //on récupère l'id
        else
            if($flag === false)
                throw new \Exception("erreur lors de la reqête insertion - erreur:".Util::printPdoError($conn->errorInfo()));
        
        return $flag;
    }

    /*________________________________________________________________________*/
    /**
     * Contruit la requete insert en utilisant un prepareStatement
     * @param <string> $table le nom de la table
     * @param <array> $elements
     * @return <int> l'identifiant de la ligne insérée
     */
    public static function insertPrepareStatement($table, array $elements)
    {
        Util::emptyException($table);
        Util::emptyException($elements);
        $conn = DalPeer::getConnection();

        $fieldNames = array_keys($elements); //recupère le nom des champs

        $query = 'INSERT INTO '.$table;

        $fields = '( ' . implode(' ,', $fieldNames) . ' )';
        $values = '(:' . implode(', :', $fieldNames) . ' )';

        $query .= $fields.' VALUES '.$values;

        $stmt = $conn->prepare($query);

        $flag = $stmt->execute($elements);
        $stmt->closeCursor();

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('insert: '.$query.' --> nbLigneInsert='.$flag);

        if($flag === true)
            $flag = $conn->lastInsertId(); //on récupère l'id
        else
            if($flag === false)
                throw new \Exception("erreur lors de la reqête insertion - erreur:".Util::printPdoError($conn->errorInfo()));

        return $flag;
    }

    /*________________________________________________________________________*/
    /**
     * Contruit la requete update
     * @param <string> $table
     * @param <array> $update
     * @param <array|string> $where
     * @return <int> le nombre de ligne modifiée
     */
    public static function update($table, array $update, $where)
    {
        Util::emptyException($table);
        Util::emptyException($update);
        Util::emptyException($where);

        $conn = DalPeer::getConnection();
        $query = 'UPDATE '.$table.' SET ';

     	 $i=0;
    	 foreach ($update as $key => $value)
    	 {
    	    $query .= $key.'='.$conn->quote($value,\PDO::PARAM_STR);
    	    if ($i != count($update) - 1)
    	    {
    		      $query .= ", ";
    	    }
    	    $i++;
    	 }

        $query .= static::getClauseWhere($where);

        $flag = $conn->exec($query);

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('update: '.$query.' --> nbLigneUpdate='.$flag);

        if($flag === false)
            throw new \Exception("erreur lors de la reqête update - erreur:".Util::printPdoError($conn->errorInfo()));
        
        return $flag;
    }

    /*________________________________________________________________________*/
    /**
    * Contruit la requete update
    * @param <string> $table
    * @param <array> $update
    * @param <array> $where
    * @return <int> le nombre de ligne modifiée
    */
    public function updatePrepareStatement($table, array $update, array $where)
    {
        Util::emptyException($table);
        Util::emptyException($update);
        Util::emptyException($where);

        $conn = DalPeer::getConnection();
        $query = 'UPDATE '.$table.' SET ';

        $updateKeys = array_keys($update);
        $whereKeys = array_keys($where);

        $countUpdate = count($updateKeys);
        for($i = 0; $i < $countUpdate ; $i++) //construction de la première partie set titre=:titre, message=:message
        {
            $query.= $updateKeys[$i]." = :".$updateKeys[$i];
            if($i != $countUpdate-1)
                $query.=", ";
        }

        $query .= " WHERE ";

        $countWhere = count($whereKeys);
        for($i = 0; $i < $countWhere ; $i++)
        {
            $query.=$whereKeys[$i]." = :".$whereKeys[$i];
            if($i != $countWhere-1)
                $query .= " and ";
        }

        $args = array_merge($update, $where);//on fusionne les 2 tableaux pour le prepareStatement

        $sth = $conn->prepare($query);
        $flag = $sth->execute($args);

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('update: '.$query.' --> nbLigneUpdate='.$flag);

        if($flag === false)
            throw new \Exception("erreur lors de la reqête update - erreur:".Util::printPdoError($conn->errorInfo()));

        return $flag;
    }
    
    /*________________________________________________________________________*/
    /**
     * Contruit la requete delete
     * @param <string> $table nom de la table
     * @param array|string $where
     * @return <int> le nombre de ligne supprimée
     */
    public static function delete($table, $where = null)
    {
        Util::emptyException($table);

	      $conn = DalPeer::getConnection();
        $query = 'DELETE FROM '.$table;

        $query .= static::getClauseWhere($where);

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);

        $flag = $conn->exec($query);
        
        if($logger->isDebugEnabled())
            $logger->debug('delete: '.$query." --> nbLigneDelete=".$flag);
            
        if($flag === false)
            throw new \Exception("erreur lors du delete de l'objet en base - erreur:".Util::printPdoError($conn->errorInfo()));

        return $flag;
    }

    /*________________________________________________________________________*/
    /**
     * construit la requete sql select
     * @param <string> $table
     * @param array $elements
     * @param <array|string> $where
     * @param <array> $order
     * @param <bool> $desc
     * @param <int|array> $limit
     * @return <array<stdclass>>  la liste des enregistrements
     */
    public static function select($table, array $elements = null, $where = null,array $order = null,$desc = null, $limit = null)
    {
        Util::emptyException($table);

	      $conn = DalPeer::getConnection();
        $query = "SELECT ";

        if(empty($elements))
            $query .= " * ";
        else
            $query .= implode(",", $elements);
        
        $query .= " FROM " . $table;

        $query .= static::getClauseWhere($where);
        
        if(!empty($order))
        {
            $query .= " ORDER BY ";
            $countOrder = count($order);

            for ($i = 0; $i < $countOrder; $i++)
            {
                $query .= $order[$i];
                
           		  if($desc !== null && $desc === true) $query .=" DESC ";
          		  if ($i < count($order) - 1)
                {
                    $query .= ", ";
                }
            }
        }
        if($limit !== null )
        {
            if(is_array($limit))
            {
                if(count($limit) === 2)
                    $query .= " LIMIT ".$limit[0].", ".$limit[1];
                else
                    throw new \Exception("erreur: 2 arguments attendus pour LIMIT");
            }
            else
                $query .= " LIMIT ".$limit;
        }

        $recordset = $conn->query($query);

	      $result = null;

        if($recordset === false)
            throw new \Exception("erreur lors de la reqête :".$query." - erreur:".Util::printPdoError($conn->errorInfo()));
        else
      	{
            $recordset->setFetchMode(\PDO::FETCH_OBJ);
      	    $result = $recordset->fetchAll();
      
            $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
            if($logger->isDebugEnabled())
                $logger->debug('select: '.$query." --> result: ".Util::get_print_contents($result));
      	}
 
        return $result;
    }

    /*______________________________________________________________________________________________________________________________*/
     /**
     * construit la requete sql select avec un prepareStatement
     * @param <string> $table
     * @param array $elements
     * @param <array> $where
     * @param <array> $order
     * @param <bool> $desc
     * @param <int|array> $limit
     * @return <array<stdclass>>  la liste des enregistrements
     */
    public function selectPrepareStatement($table, array $elements = null,array $where = null, array $order = null,$desc = null, $limit = null)
    {
        Util::emptyException($table);

	      $conn = DalPeer::getConnection();
        $query = "SELECT ";

        if(empty($elements))
            $query .= " * ";
        else
        {
            $countInsert = count($elements);
            for($i = 0; $i < $countInsert ; $i++) //construction de la première partie set titre=:titre, message=:message
            {
                $query.= $elements[$i];
                if($i != $countInsert-1)
                    $query.=", ";
            }
        }

        $query .= " FROM " . $table;
        
        if(!empty($where))
        {
            $query .= " WHERE ";
            $whereKeys = array_keys($where);
            $countWhere = count($whereKeys);
            for($i = 0; $i < $countWhere ; $i++)
            {
                $query.=$whereKeys[$i]." = :".$whereKeys[$i];
                if($i != $countWhere-1)
                    $query .= " and ";
            }
        }

        if(!empty($order))
        {
            $query .= " ORDER BY ";
            $countOrder = count($order);
	          for ($i = 0; $i < $countOrder; $i++)
            {
                $query .= $order[$i];
          		  if($desc !== null && $desc === true) $query .=" DESC ";
          		  if ($i < count($order) - 1)
                {
                    $query .= ", ";
                }
            }
        }

        if($limit !== null )
        {
            if(is_array($limit))
            {
                if(count($limit) === 2)
                    $query .= " LIMIT ".$limit[0].", ".$limit[1];
                else
                    throw new \Exception("erreur: 2 arguments attendus pour LIMIT");
            }
            else
                $query .= " LIMIT ".$limit;
        }

        $sth = $conn->prepare($query);
        $flag = $sth->execute($where);

        if($flag === false)
            throw new \Exception("erreur lors de la reqête select : $query - erreur:".Util::printPdoError($sth->errorInfo()));

        $sth->setFetchMode(\PDO::FETCH_OBJ);
	      $result = $sth->fetchAll();

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('select: '.$query." --> result: ".Util::get_print_contents($result));
                
        return $result;
    }

    /*________________________________________________________________________*/
    /**
     * Execute une requete sql
     * @param <type> $query
     * @return <PDOStatement> recordset
     */
    public static function query($query)
    {
        Util::emptyException($query);
        
        $conn = DalPeer::getConnection();
        $recordset = $conn->query($query);

	      $result = null;

        $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
        if($logger->isDebugEnabled())
            $logger->debug('query_object: '.$query." --> result: ".Util::get_print_contents($result));

        if($recordset === false)
            throw new \Exception("erreur lors de l'execution de la reqête:".$query." - erreur:".Util::printPdoError($conn->errorInfo()));
        
        return $recordset;
    }
    
    /*________________________________________________________________________*/
    /* execute une requete sql et renvoi un tableau de tableau associatif*/
    public static function query_assoc($query)
    {
        $recordset = static::query($query);
        $recordset->setFetchMode(\PDO::FETCH_ASSOC);
	      $result = $recordset->fetchAll();
	
        return $result;
    }

    /*________________________________________________________________________*/
    /* execute une requete sql et renvoi un tableau d'objet*/
    public static function query_object($query)
    {
        $recordset = static::query($query);
        $recordset->setFetchMode(\PDO::FETCH_OBJ);
	      $result = $recordset->fetchAll();

        return $result;
    }

    /*________________________________________________________________________*/
    /* constuit la requete count */
    public static function count($table,$where = null)
    {
        Util::emptyException($table);

        $conn = DalPeer::getConnection();
        $query = "SELECT COUNT(*) as total FROM ".$table;

        $query .= static::getClauseWhere($where);

	      $recordset = $conn->query($query);

        if($recordset !== false)
        {
            $result = $recordset->fetch(\PDO::FETCH_ASSOC);           
            return $result["total"];
        }
        else
            if(!static::existTable($table)) //pour aider le debogage
                throw new \Exception("la table ".$table." n'existe pas");
            else
               throw new \Exception("erreur lors de l'execution de la reqête count - erreur:".Util::printPdoError($conn->errorInfo()));
    }
}
?>

/****************** la DAO ********************/
<?php
namespace GenDao;
/**
 * Description of Dao
 *
 * @author Guillaume Genet
 */
require_once realpath(dirname(__FILE__)).'/../model_autoload.php';


class Dao 
{
    /** Correspond à la clé primaire de la base de données */
    public static $ID = "id";

    /** tableau associatif permettant de stocker les champs issus de la base de données*/
    public $attributs = null;

    /** le nom de la classe source*/
    public $className = null;

    public $isNewInstance = false;

    public $isDeleted = false;

    /*________________________________________________________________________*/
    public static function getPrimaryKeyField()
    {
        return self::$ID;
    }
    
    /*________________________________________________________________________*/
    protected function setAttributs(array $attributs)
    {
        $this->attributs = $attributs;
    }

    /*________________________________________________________________________*/
    protected function initFields()
    {
        $champTable = SqlRequest::showColumns($this->className);
        if($champTable != null)
        {
            //construction des attributs de la classe
            if($this->attributs == null)
                foreach ($champTable as $field)
                {
                    $temp = strtolower($field['Field']);
                    $this->attributs[$temp] = null;
                }
        }
        else
            throw new \Exception($this->className." n'existe pas dans la base de données");
    }

    /*________________________________________________________________________*/
    /** constructeur */
    public function __construct($args=null)
    {
    	  //SqlRequest::query('SET NAMES utf8');
        $this->attributs = array();
        $this->className = get_called_class();
        $this->isNewInstance = true;
        $this->isDeleted = false;

        $this->initFields();
    }

    /*________________________________________________________________________*/
    public function isNew()
    {
         return $this->isNewInstance;
    }

    /*________________________________________________________________________*/
    protected function setNewInstance($bool)
    {
        $this->isNewInstance = $bool;
    }

    /*________________________________________________________________________*/
    public function isDeleted()
    {
         return $this->isDeleted;
    }

    /*________________________________________________________________________*/
    protected function setDeleted($bool)
    {
        $this->isDeleted = $bool;
    }

    /*________________________________________________________________________*/
    public function getClassName()
    {
        return $this->className;
    }

    /*________________________________________________________________________*/
    /* constuit la requete count */
    public static function count()
    {
        return SqlRequest::count(get_called_class());
    }

    /*________________________________________________________________________*/
    /**
     * Permet de convertir un objet de type stdClass(PDO) en class courante
     * @param stdClass $stdClass
     * @return <Object>
    */
    public static function convertToClass(\stdClass $stdClass)
    {
        $class = get_called_class();
        $dynamicClass = new $class; //nouvelle instance de classe
        $dynamicClass->setNewInstance(false);

        //convertion
        foreach ($stdClass as $champ=>$valeur)
        {
            $dynamicClass->$champ = $valeur;
        }

        return $dynamicClass;
    }

    /*________________________________________________________________________*/
    /**
     * Permet de récuperer l'objet en fonction de l'identifiant
     * @param <type> $id
     * @return <Object> une instance de classe
     */
    public static function getById($id)
    {
        $result = SqlRequest::selectPrepareStatement(get_called_class(),null,array(self::$ID=>$id));

        if(!empty($result))
        {
            $count = count($result);
            if($count === 1)
                return self::convertToClass($result[0]);
            else
                if($count > 1)
                    throw new \Exception("l'identifiant ".$id." est présent plusieurs fois dans la base de données");
        }
        return null;
    }

    /*________________________________________________________________________*/
    /* fait un select * sur la table */
    public static function getAll()
    {
        $stmt = SqlRequest::query("select * from ".get_called_class());
        //$stmt->setFetchMode(\PDO::FETCH_CLASS,get_called_class(),null);
        $stmt->setFetchMode(\PDO::FETCH_OBJ); 
        $result = $stmt->fetchAll();
        
      	foreach ($result as $line) //parcour des enregistrements
      	{
                  $listObjects[] = self::convertToClass($line);
      	}
         
        $stmt -> closeCursor();
         
        return $listObjects;
    }

    /*________________________________________________________________________*/
    /**
     * Permet de récuperer tous les objets en fonction des paramètres
     * @param <array|string>  $where la clause where de la requête
     * @param <numeric|array> $limit le nombre d'enregistrement envoyé
     * @param <array> $order un array contenant les champs de table, permet de trier les éléments
     * @param <boolean> $desc  vrai = tri décroissant, tri croissant sinon
     * @return <array> un array contenant les objets
     */
    public static function get($where = null, array $order = null, $desc = false, $limit = null)
    { 
        $listObjects = array();

        $recordset = SqlRequest::selectPrepareStatement(get_called_class(),null,$where,$order,$desc,$limit);
        foreach ($recordset as $line) //parcour des enregistrements
        {
            $listObjects[] = self::convertToClass($line);
	      }
    
	      return $listObjects;
    }

    /*________________________________________________________________________*/
    /** Permet de sauvegarder l'objet */
    public function save()
    {
        $newInstance = $this->isNew();
        $dal = DalPeer::getConnection();
        $flag = 0;
        
        if($newInstance)//on fait un insert en base
        {
            $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
            if($logger->isDebugEnabled())
              $logger->debug('doSave:insert');

            $flag = SqlRequest::insert($this->className, $this->attributs);
            if($flag >= 0)
            {
                $this->attributs[self::$ID] = $flag; //ajout de l'attribut id
                $this->setNewInstance(false);
            }
        }
        else //on fait un update en base
        {
            if(!$this->isDeleted())
            {
                $logger = \Logger::getLogger(basename(dirname(__FILE__)).'.'.__CLASS__);
                if($logger->isDebugEnabled())
                    $logger->debug('doSave:update');
                    
                $flag = SqlRequest::update($this->className, $this->attributs, array(self::$ID=>$this->attributs[self::$ID]));
            }
            else
                throw new \Exception("erreur: impossible de sauvegarder des données préalablement supprimées");
        }
        
        return $flag;
    }

     /*________________________________________________________________________*/
    /** Permet de supprimer l'objet */
    public static function deleteById($id)
    {
        $dal = DalPeer::getConnection();
        $flag = SqlRequest::delete(get_called_class(),array(self::$ID => $id));

        return $flag;
    }

    /*________________________________________________________________________*/
    /** Permet de supprimer l'objet */
    public function delete()
    {
        $dal = DalPeer::getConnection();
        $flag = 0;
        
        if(!$this->isDeleted())
        {
            $flag = SqlRequest::delete($this->className,array(self::$ID => $this->attributs[self::$ID]));
            $this->setDeleted(true);
         }
         else
             throw new \Exception("erreur:appel de la fonction delete plusieurs fois à la suite");

         return $flag;
    }

    /*________________________________________________________________________*/
    /**
     * Permet d'accéder aux attributs de la classe (sans l'utilisation d'un getter ex: echo $article->titre;)
     * @param <string> $name le nom de l'attribut
     * @return <array> le tableau de résultat
     */
    public function  __get($name)
    {
	      $name = strtolower($name);
        if(array_key_exists($name, $this->attributs))
        {
            return $this->attributs[$name];
        }
        else
            throw new \Exception( "l'attribut ".$name. " n'existe pas pour l'objet ".$this->className);
    }

    /*________________________________________________________________________*/
    /** Permet d'accéder aux attributs de la classe (sans l'utilisation d'un setter ex: $article->titre='football')
     * @param <string> $name le nom de l'attribut
     * @param <object> $value 
     * @return <array> le tableau de résultat
     */
    public function  __set($name,  $value)
    {
	      $name = strtolower($name);
        if(array_key_exists($name, $this->attributs))//pour pas ajouter un element au tableau assosiatif
        {
            $this->attributs[$name] = $value;
        }
        else
            throw new \Exception("l'attribut ".$name. " n'existe pas pour l'objet ".$this->className);
    }

    /*________________________________________________________________________*/
    /** appel de méthode */
    public function __call($name,  $arguments)
    {
        $getterSetter = strtolower(substr($name, 0,3));

        //pour accéder aux attributs en utilisant les getters
        if($getterSetter === "get")
        {
            $attribut = strtolower(substr($name, 3));//nom de l'attribut
            return $this->__get($attribut);
        }
	      //pour affecter des attributs en utilisant les setters
        else if($getterSetter === "set")
        {
            $attribut = strtolower(substr($name, 3));
            $this->__set($attribut, $arguments[0]);
        }
        else
            throw new \Exception($name." est une méthode inconnue");
    }
}
?>


 Fichier Zip

Les Membres Club peuvent télécharger directement un fichier contenu dans le zip sans télécharger le zip en entier !

Télécharger le zip


 Historique

29 mai 2010 19:33:03 :
modification présentation
01 juin 2010 23:49:44 :
/

 Sources du même auteur

Source avec Zip CONVERSION DES UNITÉS INFORMATIQUE (O, KIO, MIO, GIO, TIO......
Source avec Zip Source avec une capture SYSTÈME DE PAGINATION COMPLET

 Sources de la même categorie

Source avec Zip GÉNÉRATION AUTOMATIQUE DE FICHIER .CLASS.PHP EN FONCTION D'U... par ig3
CLASSE D'OBJET DE CRYPTAGE ET DÉCRYPTAGE DE CHAINES DE CARAC... par 8Tnerolf8
Source avec Zip MY.DEVIANTART API par inwebo
CLASSE DE GESTION DE "VARIABLES GLOBALES D'ENVIRONNEMENT" par pifou25
Source avec Zip COLLECTION.CLASS.MIN.PHP par thunderhunter

Commentaires et avis

Commentaire de aKheNathOn le 31/05/2010 10:23:51 10/10

joli travail 10/10, 100% d'accord avec toi sur l'approche dao, et la source est propre.

Pour l'optimisation, dans getAll, sur le fetchMode, tu peux mettre directement le nom de ta classe :
http://www.php.net/manual/en/pdostatement.setfetchmode.php

-> Cela t'évitera de boucler dans la fonction convertToClass.

La partie transaction est très "intéressante" par contre très mal utilisée dans ton contexte :

La transaction peut être justifiée à partir d'au moins 2 requêtes, car si tu n'en fait qu'une seule, et que celle-ci génère une erreur, le rollback ne va fonctionner que sur la dernière requête validée, or dans ton cas aucune vu qu'elle a généré une erreur. Cela va donc si tu fais une boucle d'updates ralentir son fonctionnement : il aurais fallu que ce soit au niveau de la logique métier que les transactions soient implémentée en fonction justement du découpage fonctionnel.

Dommage également qu'au niveau définition on ne sache pas le typage des champs, un auto-increment, une date, un entier ou bien un enum ... Cela aurait permis une validation en amont de l'affection d'une valeur.

Autre fonctionnalité manquante, la possibilité de référencer des objets dans tes instances dao, style author pour post je présume que ce sera un integer ...

C'est un sujet très intéressant que tu abordes,
Bonne continuation,
Akh

Commentaire de MrJAY42 le 31/05/2010 11:19:24

Ce code m'a l'air bien sous tout rapport ^^

Un truc que je ne comprends pas cependant :
La fonction "public static function clause(array $clause, PDO $conn = null)"
Je ne vois pas son intérêt...
Généré un WHERE dont chaque élément est forcément séparé par un AND ?
Je n'ai peut être pas compris la façon de fonctionner de cette fonction, mais ça me semble hautement inutile comme fonction...Enfin c'est surtout inutilisable.

Commentaire de genetApt151 le 05/06/2010 22:44:35

Pour le fonction convertToClass, j'ai pas le choix, $PDO::FETCH_CLASS ne fonctionne pas avec les méthodes magiques.

Pour la possibilité de référencer des objets, c'est plus une DAO mais une ORM et c'est plus compliqué voir impossible de faire quelque chose de générique.

Commentaire de gr43 le 12/06/2010 18:46:47

Salut,
pour orm php : doctrine, propel ...
génération de model automatique en fonction schema table

Commentaire de gregos66 le 16/07/2010 11:53:53

Salut,
Peut-on utiliser ton programme si une table comporte 2 clés primaire, stp? (table de relation n n).
Je te remercie par avance.

Commentaire de genetApt151 le 16/07/2010 14:33:01

non, cela ne gère pas les relations, il faut utiliser une ORM
ex : doctrine

Commentaire de gregos66 le 16/07/2010 15:49:52

Ma question va peut être être bête, mais est-il utile de combiné ton application avec doctrine ou il faut que je me serve que du package doctrine, stp?

Commentaire de genetApt151 le 16/07/2010 19:06:48

doctrine fait tout, les accès au données (DAO) et les relations(ORM)et plein d'autres choses...

 Ajouter un commentaire


Discussions en rapport avec ce code source dans le forum

[SOAP] Problème de namespace dans le soap header [ par cabrinha ] Bonjour, J'ai un service web qui tourne en .NETJe dois développer un client en PHP5. J'ai un problème de formattage de mon en-tête SOAP. En effet, il PHP5 et SOAP. Probleme namespace [ par Soulant ] Bonjour,J'essaie de créer un client SOAP en PHP, mais j'ai des problêmes avec les namespaces.En effet, un client créé en C# envoie une un message comm


Nos sponsors


Sondage...

CalendriCode

Mai 2012
LMMJVSD
 123456
78910111213
14151617181920
21222324252627
28293031   

Consulter la suite du CalendriCode

A découvrir



 
Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel (EBArtSoft), Merci à Vincent pour ses précieux conseils.
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés

Google Coop CodeS-SourceS Google Coop CodeS-SourceS
Temps d'éxécution de la page : 0,390 sec (4)

Nous contacter | Annoncer sur CodeS-SourceS | Mentions légales