Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] silnik bazy danych PDO
Forum PHP.pl > Forum > Przedszkole
greg.paw.90
Witam,
na wstępie przepraszam jeśli nie ten działa, ale to co zrobiłem traktuję jako naukę (stąd znalazło się to w przedszkolu a nie w ocenach) dlatego proszę o porady co robię źle, czy to co w ogóle zrobiłem ma sens.

Chcę nauczyć się programowania obiektowego w php... najlepiej według mnie uczy się rozwiązując jakiś problem / pisząc jakiś skrypt... dlatego też postanowiłem, że pod swojego CMS (jak i sam system przerobie pod obiektów-kę) napiszę główny silnik do obsługi zapytań do bazy danych (kolejne klasy będą rozszerzeniem tego silnika - np. wczytywanie/dodawanie/edycja newsów). Szperałem w internecie na temat samego OOP i natknąłem się na bibliotekę PDO. Na podstawie tego co wyczytałem w php.net stworzyłem obiektowo (tak mi się wydaje) główny silnik do obsługi mojego systemu CMS. Teraz bardzo proszę "wyjadaczy" o porady czy to co zrobiłem jest OK, co należy zmienić czego unikać.

KOD:

  1. <?php
  2. /*
  3.  * Silnik Systemu v. 0.1a
  4.  */
  5. class DBEngine{
  6.  
  7. private $engine;
  8. private $host;
  9. private $database;
  10. private $user;
  11. private $pass;
  12. private $codetype;
  13.  
  14. public $db;
  15. public $errors;
  16.  
  17. public function __construct($dbCONFIG = NULL){
  18.  
  19. if($dbCONFIG == NULL){
  20. $this->engine = 'mysql';
  21. $this->host = 'localhost';
  22. $this->database = 'test';
  23. $this->user = 'root';
  24. $this->pass = '';
  25. $this->codetype = 'utf-8';
  26. }
  27. else{
  28. $this->engine = $dbCONFIG[0];
  29. $this->host = $dbCONFIG[1];
  30. $this->database = $dbCONFIG[2];
  31. $this->user = $dbCONFIG[3];
  32. $this->pass = $dbCONFIG[4];
  33. $this->codetype = $dbCONFIG[5];
  34. }
  35.  
  36. $dns = $this->engine . ':dbname=' . $this->database . ';host=' . $this->host;
  37. $dbuser = $this->user;
  38. $dbpass = $this->pass;
  39.  
  40. try {
  41. $this->db = new PDO($dns,$dbuser,$dbpass);
  42. self :: setEncoding($this->codetype);
  43. } catch (PDOException $e) {
  44. $this->errors[] = $e->getMessage();
  45. }
  46.  
  47. }
  48.  
  49. private function setEncoding($codetype = 'utf-8'){
  50.  
  51. try {
  52. $sth = $this->db->prepare('SET NAMES :codetype; SET CHARACTER SET :codetype');
  53. $sth->bindParam(':codetype', $codetype, PDO::PARAM_STR);
  54. $sth->execute();
  55. $sth->closeCursor();
  56. } catch (PDOException $e) {
  57. $this->errors[] = $e->getMessage();
  58. }
  59.  
  60. }
  61.  
  62. public function query($sql = NULL){
  63.  
  64. if($sql != NULL){
  65. try {
  66. $sth = $this->db->prepare($sql);
  67. $sth->execute();
  68. $sth->closeCursor();
  69. } catch (PDOException $e) {
  70. $this->errors[] = $e->getMessage();
  71. }
  72. } else {
  73. $this->errors[] = 'Not defined queries';
  74. }
  75.  
  76. }
  77.  
  78. public function fetch($sql = NULL, $type = 1){
  79.  
  80. if($sql != NULL){
  81. try {
  82. $sth->self :: query($sql);
  83. switch($type){
  84. case '1':
  85. $result = $sth->fetch(PDO::FETCH_ASSOC);
  86. break;
  87. case '2':
  88. $result = $sth->fetchAll();
  89. break;
  90. }
  91. $sth->closeCursor();
  92. return $result;
  93. } catch (PDOException $e) {
  94. $this->errors[] = $e->getMessage();
  95. }
  96. } else {
  97. $this->errors[] = 'Not defined queries';
  98. }
  99.  
  100. }
  101.  
  102. public function fetchArray($argument = NULL, $table = NULL, $order = 'id', $type = 'DESC', $limit = NULL, $where = NULL){
  103.  
  104. if($argument != NULL && $table != NULL){
  105. try {
  106. if($limit != NULL || $where != NULL){
  107. if($limit != NULL && $where != NULL){
  108. $sth = $this->db->prepare("SELECT $argument FROM $table WHERE $where ORDER BY $order $type LIMIT $limit");
  109. } elseif($limit != NULL && $where == NULL){
  110. $sth = $this->db->prepare("SELECT $argument FROM $table ORDER BY $order $type LIMIT $limit");
  111. } else{
  112. $sth = $this->db->prepare("SELECT $argument FROM $table WHERE $where ORDER BY $order $type");
  113. }
  114. } else{
  115. $sth = $this->db->prepare("SELECT $argument FROM $table ORDER BY $order $type");
  116. }
  117. $sth->execute();
  118. $result = $sth->fetchAll();
  119. $sth->closeCursor();
  120. return $result;
  121. } catch (PDOException $e) {
  122. $this->errors[] = $e->getMessage();
  123. }
  124. } else {
  125. $this->errors[] = 'Not defined arguments or table';
  126. }
  127.  
  128. }
  129.  
  130. public function fetchRow($argument = NULL, $table = NULL, $id = NULL, $where = ''){
  131.  
  132. if($argument != NULL && $table != NULL && $where != NULL){
  133. try {
  134. $sth = $this->db->prepare("SELECT $argument FROM $table WHERE id=:id $where");
  135. $sth->bindValue(":id", $id, PDO::PARAM_INT);
  136. $sth->execute();
  137. $result = $sth->fetch(PDO::FETCH_ASSOC);
  138. $sth->closeCursor();
  139. return $result;
  140. } catch (PDOException $e) {
  141. $this->errors[] = $e->getMessage();
  142. }
  143. } else {
  144. $this->errors[] = 'Not defined arguments or table or where';
  145. }
  146.  
  147. }
  148.  
  149. public function insert($table = NULL, $data = NULL){
  150.  
  151. if($table != NULL && $data != NULL){
  152. $columns = '';
  153. $values = '';
  154. try {
  155. foreach ($data as $column => $value) {
  156. $columns .= ($columns == '') ? '' : ', ';
  157. $columns .= $column;
  158. $values .= ($values == '') ? '' : ', ';
  159. $values .= ":$value";
  160. }
  161. $sth = $this->db->prepare("INSERT INTO $table ($columns) VALUES ($values)");
  162. foreach ($data as $column => $value) {
  163. $sth->bindValue(":$value", $value, PDO::PARAM_STR);
  164. }
  165. $sth->execute();
  166. $sth->closeCursor();
  167. return $this->db->lastInsertId();
  168. } catch (PDOException $e) {
  169. $this->errors[] = $e->getMessage();
  170. }
  171. } else {
  172. $this->errors[] = 'Not defined table or data';
  173. }
  174.  
  175. }
  176.  
  177. public function update($table = NULL, $values = NULL, $id = NULL){
  178.  
  179. if($table != NULL && $id != NULL){
  180. try {
  181. $sth = $this->db->prepare("UPDATE $table SET $values WHERE id=:id");
  182. $sth->bindValue(":id", $id, PDO::PARAM_INT);
  183. $sth->execute();
  184. $sth->closeCursor();
  185. return true;
  186. } catch (PDOException $e) {
  187. return true;
  188. $this->errors[] = $e->getMessage();
  189. }
  190. } else {
  191. $this->errors[] = 'Not defined table or values or id';
  192. }
  193.  
  194. }
  195.  
  196. public function delete($table = NULL, $id = NULL){
  197.  
  198. if($table != NULL && $id != NULL){
  199. try {
  200. $sth = $this->db->prepare("DELETE FROM $table WHERE id=:id");
  201. $sth->bindValue(":id", $id, PDO::PARAM_INT);
  202. $sth->execute();
  203. $sth->closeCursor();
  204. } catch (PDOException $e) {
  205. $this->errors[] = $e->getMessage();
  206. }
  207. } else {
  208. $this->errors[] = 'Not defined table or id';
  209. }
  210.  
  211. }
  212.  
  213. public function count($sql = NULL, $type = NULL){
  214.  
  215. if($sql != NULL){
  216. try {
  217. $sth = $this->db->prepare($sql);
  218. switch($type){
  219. case 'col':
  220. $count = $sth->columnCount();
  221. break;
  222. case 'row':
  223. $sth->execute();
  224. $count = $sth->rowCount();
  225. break;
  226. }
  227. return $count;
  228. $sth->closeCursor();
  229. } catch (PDOException $e) {
  230. $this->errors[] = $e->getMessage();
  231. }
  232. } else {
  233. $this->errors[] = 'Not defined queries';
  234. }
  235.  
  236. }
  237.  
  238. public function getError(){
  239.  
  240. $view = '';
  241.  
  242. if(count($this->errors) > 0){
  243. $view = '<ul>';
  244. foreach($this->errors as $error){
  245. $view .= '<li>' . $error . '</li>';
  246. }
  247. $view .= '</ul>';
  248. }
  249.  
  250. return $view;
  251.  
  252. }
  253.  
  254. public function __destruct(){
  255.  
  256. $this->db = NULL;
  257.  
  258. }
  259.  
  260. }
  261. ?>


Dziękuje za wszelkie uwagi i proszę o wyrozumiałość.

Pozdrawiam Grzegorz smile.gif
Mephistofeles
Cytat
napiszę główny silnik do obsługi zapytań do bazy danych (kolejne klasy będą rozszerzeniem tego silnika - np. wczytywanie/dodawanie/edycja newsów).

W żadnym wypadku tak nie rób, to zaprzeczenie wszystkich wzorców projektowych...
Instancję twojej klasy możesz przekazywać w konstruktorze, czy w dowolny inny sposób do pozostałych klas, ale nie dziedzicz wszystkiego po jednej głównej klasie.
Btw do tego służy m.in. wzorzec Dependency Injection, od biedy można użyć też Singletona/Rejestru.

Poza tym twoja klasa w zasadzie nic specjalnego nie robi, na dodatek traci większość zalet podpinania parametrów (bo $where itp. dopisujesz po prostu do zapytania). Lepiej przekazuj po prostu obiekt PDO między klasami.
greg.paw.90
dziękuje za odpowiedź...

Cytat
Instancję twojej klasy możesz przekazywać w konstruktorze, czy w dowolny inny sposób do pozostałych klas, ale nie dziedzicz wszystkiego po jednej głównej klasie.


a ja myślałem, że w ten sposób nie będę musiał wszędzie gdzie chce wykorzystać zapytania bazy danych tworzyć nowego obiektu głównego silnika.. chyba że źle rozumiem to wszystko...

czyli nie mam dziedziczyć tylko zrobić tak:

  1. class NewsClass {
  2.  
  3. private $db;
  4.  
  5. public function __construct(){
  6. $this->db = new DBEngine;
  7. }
  8.  
  9. ...
  10.  
  11. }


jeśli źle to zrobiłem to czy możesz mnie nakierować, pokazać jak to zrobić smile.gif
Mephistofeles
Nie, tak też nie biggrin.gif.
  1. $news = new NewsClass($db, ...)

Albo zrób sobie fabrykę zwracającą modele:
  1. $news = $factory->getModelClass('News')

która zwróci obiekt z już ustawionym polem $db.

I tak jak mówiłem nie łącz po prostu łańcuchów w zapytaniu, bo tracisz większość zalet zapytań preparowanych (m.in. ochronę przed SQL Injection).
greg.paw.90
hmm... coś takiego ?

  1. class Factory {
  2.  
  3. public $db;
  4.  
  5. public function __construct() {
  6.  
  7. require_once 'DbEngine.php';
  8. $this->db = new DbEngine;
  9.  
  10. }
  11.  
  12. public function getModelClass($name) {
  13. if (include_once $name . 'Class.php') {
  14. $classname = $name . 'Class';
  15. return new $classname($this->db);
  16. } else {
  17. throw new Exception('Driver not found');
  18. }
  19. }
  20.  
  21. }


Cytat
I tak jak mówiłem nie łącz po prostu łańcuchów w zapytaniu, bo tracisz większość zalet zapytań preparowanych


czyli zrezygnować z tych funkcji które zrobiłem i w tych klasach kolejnych tworzyć zapytania według PDO tak?
Crozin
Dlaczego uważasz, że w każdym takim "modelu" będziesz potrzebować bazy danych? Co w przypadku na przykład obiektu pobierającego dane z Twittera, YouTube czy Facebooka? Albo z pliku XML?

Przekazywanie zależności jest nieco kłopotliwe - albo rób to całkowicie ręcznie, albo skorzystaj z jakiś sensownych narzędzi jak wspomniane DI.
Mephistofeles
Możesz zrobić zapytania tak, żeby osobno doklejać np.
  1. WHERE name = ?
, a potem do tego dodawać parametry w tablicy:
  1. // przykładowo
  2. $query->where('name = ?', array($name))
greg.paw.90
a coś takiego?

  1. class Factory {
  2.  
  3. public $db;
  4.  
  5. public function __construct() {
  6.  
  7. require_once 'DbEngine.php';
  8. $this->db = new DbEngine;
  9.  
  10. }
  11.  
  12. public function getModelClass($name, $base = false) {
  13. if (include_once $name . 'Class.php') {
  14. $classname = $name . 'Class';
  15. if($base == true) {
  16. return new $classname($this->db);
  17. } else {
  18. return new $classname();
  19. }
  20. } else {
  21. throw new Exception('Driver not found');
  22. }
  23. }
  24.  
  25. }
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.