Class SPDO PDO - Apprendre-PHP.com

Rechercher
Boutique en ligne, solution e-commerce, script PHP et PERL : RAYNETTE

Class SPDO PDO

Par Vini -  10 reponses -  Le 13/09/2008 -  Flux RSS - 

Bonjour à toutes et à tous ! :)

je suis nouveau ici et je debute dans la POO ! 

Suite à un tutoriel sur apprendre-php.com j'ai repris la source puis j'y ai redefini les methode

je voulais savoir 

1) si ma classe etait correcte (ci-dessous)

2) devrais rajouter quelque chose ? (type exception ou autre idée)

j'ai bien aimer cette source car elle reprend bien le concept du singleton avec un constructeur private !

mais j'ai aussi vu d'autre source dans le meme style mais avec un constructeur public de facon à herité de la class PDO  !

quel d'après vous la meilleur sollution? si y'en a t'il une ou bien les 2 styles sont très bien aussi

auquel cas on choisi en fonction de ses besoins ?

 

Réponses apportées à cette discussion

Par Vini -  Le 13/09/2008 - 

je connais pas bien ici j'ai inserer mon code je sais pas pourquoi ca ne la pas pris !

j'ai du faire une betise!

le liens vers le tutorial d'origine :

Liens vers la source

 

My class
  1. class SPDO {
  2. /**
  3.   * Instance de la classe PDO
  4.   *
  5.   * @var PDO
  6.   * @acces private
  7.   */
  8. private $PDOInstance = null;
  9. /**
  10.   * Instance de la class SPDO
  11.   *
  12.   * @var SPDO
  13.   * @access private
  14.   * @static
  15.   */
  16. private static $instance = null;
  17. /**
  18.   * Constante: User name from the Database
  19.   * @var String
  20.   */
  21. const USERNAME = 'root';
  22. /**
  23.   * Constante: Server host
  24.   * @var String
  25.   */
  26. const HOST = 'localhost';
  27. /**
  28.   * Constante: Password
  29.   * @var String
  30.   */
  31. const PASSWORD = 'Nemesis';
  32. /**
  33.   * Constante: Database name
  34.   * @var String
  35.   */
  36. const DATABASE = 'agenda';
  37. /**
  38.   * Constructor
  39.   * @access private
  40.   * @param void
  41.   * @return void
  42.   * @see PDO::__construct()
  43.   */
  44. private function __construct() {
  45. try {
  46. $this->PDOInstance = new PDO('mysql:dbname='.self::DATABASE.';host='.self::HOST,self::USERNAME,self::PASSWORD);
  47. $this->PDOInstance->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
  48. } catch (PDOException $e) {
  49. echo "<b>Error PDO:</b> ".$e->getMessage()."<br />\n";
  50. }
  51. }
  52. /**
  53.   * Empeche la copie externe de l'instance
  54.   * @access private
  55.   */
  56. private function __clone() {
  57. throw new Exception('Le clonage de SPDO n\'est pas autoris&eacute;');
  58. }
  59. /**
  60.   * Create and return SPDO Object
  61.   *
  62.   * @access public
  63.   * @static
  64.   * @param void
  65.   * @return SPDO $instance
  66.   */
  67. public static function getInstance()
  68. {
  69. if(is_null(self::$instance))
  70. {
  71. self::$instance = new SPDO();
  72. }
  73. return self::$instance;
  74. }
  75. /**
  76.   * Initiates a transaction
  77.   *
  78.   * @return <bool>
  79.   */
  80. public function beginTransaction() {
  81. return $this->PDOInstance->beginTransaction();
  82. }
  83. /**
  84.   * Commits a transaction
  85.   *
  86.   * @return <bool>
  87.   */
  88. public function commit() {
  89. return $this->PDOInstance->commit();
  90. }
  91. /**
  92.   * Fetch the SQLSTATE associated with the
  93.   * last operation on the database handle
  94.   *
  95.   * @return <string>
  96.   */
  97. public function errorCode() {
  98. return $this->PDOInstance->errorCode();
  99. }
  100. /**
  101.   * Fetch extended error information associated with
  102.   * the last operation on the database handle
  103.   *
  104.   * @return <array>
  105.   */
  106. public function erroInfo() {
  107. return $this->PDOInstance->errorInfo();
  108. }
  109. /**
  110.   * Executes an SQL statement, return the number of affected row
  111.   *
  112.   * @param <String> $statement
  113.   * @return <int>
  114.   */
  115. public function exec($statement) {
  116. return $this->PDOInstance->exec($statement);
  117. }
  118. /**
  119.   * Retrieve a database connection attribute
  120.   *
  121.   * @param <int> $attribute
  122.   * @return <mixed>
  123.   */
  124. public function getAttribute($attribute) {
  125. return $this->PDOInstance->getAttribute($attribute);
  126. }
  127. /**
  128.   * Return an array of available PDO drivers
  129.   *
  130.   * @return <array>
  131.   */
  132. public function getAvailabelDrivers() {
  133. return $this->PDOInstance->getAvailableDrivers();
  134. }
  135. /**
  136.   * Returns the ID of the last inserted row or sequence value
  137.   *
  138.   * @param <type> $name
  139.   * @return <type>
  140.   */
  141. public function lastInsertId($name) {
  142. return $this->PDOInstance->lastInsertId($name);
  143. }
  144. /**
  145.   *
  146.   * @param <String> $statement
  147.   * @return <type>
  148.   */
  149. public function prepare($statement,$driver_options=false) {
  150. if(!$driver_options) $driver_options=array();
  151. return $this->PDOInstance->prepare($statement,$driver_options);;
  152. }
  153. /**
  154.   * Executes an SQL statement, returning a result set as PDOStatement object
  155.   *
  156.   * @param <string> $statement
  157.   * @return PDOStatement
  158.   */
  159. public function query($statement) {
  160. try {
  161. return $this->PDOInstance->query($statement);
  162. } catch (PDOException $e) {
  163. echo $e->getMessage();
  164. }
  165. }
  166. /**
  167.   * Quotes a string for use in a query
  168.   *
  169.   * @param <type> $input
  170.   * @param <type> $parametre_type
  171.   * @return <type>
  172.   */
  173. public function quote($input, $parametre_type=0) {
  174. return $this->PDOInstance->quote($input,$parametre_type);
  175. }
  176. /**
  177.   * Rolls back a transaction
  178.   *
  179.   * @return <bool>
  180.   */
  181. public function rollBack() {
  182. return $this->PDOInstance->rollBack();
  183. }
  184. /**
  185.   * Set an attribute
  186.   *
  187.   * @param <int> $attribute
  188.   * @param <mixed> $value
  189.   * @return <bool>
  190.   */
  191. public function setAttribute($attribute, $value) {
  192. return $this->PDOInstance->setAttribute($attribute,$value);
  193. }
  194. /**
  195.   * Execute query and return one row in assoc array
  196.   *
  197.   * @param <string> $statement
  198.   * @return <type>
  199.   */
  200. public function queryFetchAllAssoc($statement) {
  201. return $this->PDOInstance->query($statement)->fetchAll(PDO::FETCH_ASSOC);
  202. }
  203. /**
  204.   * @param <type> $statement
  205.   * @return <type>
  206.   */
  207. public function queryFetchAllObj($statement) {
  208. return $this->PDOInstance->query($statement)->fetchAll(PDO::FETCH_OBJ);
  209. }
  210. public function queryFetchAllBoth($statement) {
  211. return $this->query($statement)->fetchAll(PDO::FETCH_BOTH);
  212. }
  213. /**
  214.   * Close a connection database
  215.   *
  216.   * @access public
  217.   * @return <void>
  218.   */
  219. public function close() {
  220. $this->PDOInstance = null;
  221. }
  222. }
  223. ?>

voila j'ai compris

 

 

 

 
Par Emacs -  Le 13/09/2008 - 

Salut et bienvenue sur Apprendre-PHP.com,

Ton implémentation est parfaitement correcte. Content de savoir que les tutoriels présentés sont utiles :)

La méthode avec constructeur public et héritage direct de la classe PDO ne permet pas de faire de l'instance unique puisque le pattern singleton n'est pas implémenté. Il est donc du devoir du développeur de choisir s'il veut ou non pouvoir réaliser des instances uniques ou pas issues de ses classes. Ce n'est qu'une question de goût ensuite.

Concernant ce que tu pourrais ajouter, il y'a par exemple les logs. Par exemple, avant d'exécuter les requêtes SQL avec query() ou execute(), tu loggues les requêtes SQL dans un fichier texte pour pouvoir ensuite tracer toutes les requêtes exécutées et les optimiser si besoin.

++

Hugo. 

 
Par Vini -  Le 14/09/2008 - 

merci à toi Emacs !

je connaissais pas ce site et j'avoue il est très efficasse et j'espere le voir s'etendre encore plus !

 je vais faire ce que tu me conseille !

 pour les logs faut que je travaille un peu l'algo car je suis pas encore très fort en orienté objet !

je sais ecrire dans un fichier mais la ou il faut que je reflechisse c'est comment savoir si une requete à été executé !

 je me doute que ca dois pas etre très compliqué mais j'y reflechi !

et si tu as une piste ou 2 je suis prenneur :D

merci pour ton aide

 

 
Par Emacs -  Le 14/09/2008 - 

Salut Vini,

Merci pour tes compliments, ça fait plaisir de savoir qu'Apprendre-PHP plait autant. Je suis entrain de revoir l'architecture du site. Une nouvelle version du site enrichit est prévue dans quelques mois.

En ce qui concerne les exécutions de requêtes, tu as plusieurs moyens de savoir si elles se sont bien exécutées. Tout d'abord, tu peux encapsuler tes méthodes query() et exec() dans un bloc try { } catch { }. En cas d'erreur, une exception est levée et ainsi tu peux logguer à la fois l'exception et la requête défectueuse dans un fichier de log particulier. Ensuite, tu peux également tester les valeurs de retour de certaines méthodes comme celles qui te retournent le nombre de lignes récupérées dans le cas d'une requête SELECT ou bien celle qui te donnent le nombre de lignes affectées par une requête de type UPDATE ou DELETE.

++ 

 
Par Vini -  Le 19/09/2008 - 

hello !

J'ai pas trop eu le temps de finir mais me revoila !

donc si j'ai bien compris je prend par exemple la methode exec() !

 

  1. <?php
  2.  
  3.  
  4. public function exec($statement)
  5. {
  6. try {
  7. return $this->PDOInstance->exec($statement);
  8. } catch (PDOExecption $e) {
  9.  
  10. echo $e->getMessage(); // pour afficher l'erreur
  11.  
  12. // et la par exemple j'insert dans un fichier text
  13. // avec une autre methode que je pourrais créer par exemple,
  14. // l'erreur getMessage() en y ajoutant l'heure et ce que je veux quoi
  15.  
  16. //?
  17. }
  18.  
  19.  
  20. ?>

j'espere avoir bien compris si c'est ca alors je pourrais fermer le post !

 Merci pour ton aide Emacs :D

 

 
Par Emacs -  Le 19/09/2008 - 

Salut Vini,

Oui tu as bien compris le principe. Pour pousser le bouchon un peu plus loin, tu peux opter pour une classe MyLogger utilisant elle aussi le pattern singleton. Cela donne par exemple :

  1. <?php
  2.  
  3. class MyLoggerException
  4. {
  5. }
  6.  
  7. class MyLogger
  8. {
  9. const ERROR_FATAL = 'Fatal';
  10. const ERROR_WARNING = 'Warning';
  11. const ERROR_SYSTEM = 'System';
  12. const ERROR_SERVER = 'Server';
  13. const ERROR_QUERY = 'Query';
  14.  
  15. /**
  16.   * Unique instance of MyLogger
  17.   *
  18.   * @var MyLogger|null
  19.   * @access private
  20.   * @static
  21.   */
  22. private static $_instance = null;
  23.  
  24. /**
  25.   * Log file path
  26.   *
  27.   * @var string
  28.   * @access private
  29.   * @static
  30.   */
  31. private static $_logFile = null;
  32.  
  33. /**
  34.   * Constructor
  35.   *
  36.   * @access private
  37.   */
  38. private function __construct()
  39. {
  40. }
  41.  
  42. /**
  43.   * Returns the unique instance
  44.   *
  45.   * Creates the object if doesn't exist
  46.   *
  47.   * @return unknown
  48.   */
  49. public function getInstance()
  50. {
  51. if(null === self::$_instance)
  52. {
  53. self::$_instance = new MyLogger();
  54. }
  55. return self::$_instance;
  56. }
  57.  
  58. /**
  59.   * Defines the log file
  60.   *
  61.   * @param strign $filePath
  62.   * @return MyLogger MyLogger::$_instance
  63.   */
  64. public function setLogFile($filePath)
  65. {
  66. if(!file_exists($filePath)) {
  67. throw new MyLoggerException(sprintf("%s doesn't exists !", $filePath));
  68. }
  69.  
  70. if(!is_writeable($filePath)) {
  71. throw new MyLoggerException(sprintf("%s is not writeable !", $filePath));
  72. }
  73.  
  74. self::$_logFile = $filePath;
  75. return self::$_instance;
  76. }
  77.  
  78. /**
  79.   * Log an error
  80.   *
  81.   * @param string $message
  82.   * @param string $date
  83.   * @param string $type
  84.   */
  85. public function log($message, $date = null, $type = self::ERROR_WARNING)
  86. {
  87. // Là tu loggues
  88. return self::$_instance;
  89. }
  90. }
  91. ?>

 

Et tu utilises la classe comme ça :

  1. public function exec($statement)
  2. {
  3. try {
  4. return $this->PDOInstance->exec($statement);
  5. } catch (PDOExecption $e) {
  6. try {
  7. MyLogger::getInstance()->
  8. setLogFile('/var/log/mon_site.log')->
  9. log('Exécution impossible de la requête préparée', strftime('%Y-%m-%d %H:%M:%s'), MyLogger::ERROR_FATAL)->
  10. log($statement, strftime('%Y-%m-%d %H:%M:%s'), MyLogger::ERROR_QUERY)->
  11. log($e->getMessage(), strftime('%Y-%m-%d %H:%M:%s'), MyLogger::ERROR_SERVER);
  12.  
  13. // Redirection vers erreur 500
  14. header('HTTP/1.0 500 Internal Server Error');
  15. header('Location: http://www.tonsite.com/500.php');
  16.  
  17. } catch(MyLoggerException $e) {
  18. // En prod il faudrait rediriger vers une erreur 500
  19. //die($e->getMessage());
  20. }
  21. }
  22. }

 

C'est une ébauche pour t'aider :)

++

Hugo.

 
Par Vini -  Le 20/09/2008 - 

 

Hi Emacs !

c'est une ebauche certe mais très bien expliquer !

cela me donne à reflechir et de nouvelle idées !

et je t'en remercie beaucoup ! :D

c'est pour ca que j' aime ce site simple, efficace un acceuil chaleureux !

et une réel motivation à vouloir partager les connaissances ! ;)

bref je kiff lool :D

 

 

 
Par Emacs -  Le 20/09/2008 - 

De rien :)

N'hésite pas à repasser régulièrement sur le site, mais visiblement c'est ce que tu fais ^^ 

 
Par Vini -  Le 20/09/2008 - 

oui tinquiete pas pour ça, tu risque de me voir souvent venir t'embeter mdrr

que veux tu on ne change pas une equipe qui gagne !

l'avantage ici c'est quand j'ai des questions liée à des prob je suis sur d'y trouvé une aide bien dirigée, et expliquée !

et puis les infos et tutos sont interessante

alors oui je vais squaté souvent ici c'est claire d'ailleur c'est devenu pas page d'acceuil de mon FireFox :D

 

Vini ++

 
Par paguira -  Le 29/10/2008 - 

Bonjour,

Comment utiliser cette class, avez vous un exemple de selection et d'ajout de base ?!

Je souhaite adapter cette class aux class du logiciel Thelia (http://www.thelia.fr)

 

 

 

Ajouter une réponse à la discussion

Seuls les membres loggués sont autorisés à poster dans les forums !