Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [skrypt][OBIEKT] Interpreter PDO
Forum PHP.pl > Inne > Oceny
Posio
Chciałbym poddać ocenie napisany dziś obiekt, który ma mi ułatwić i przyśpieszyć akcje związane z bazą danych.
Podkreślam ,że dopiero rozpoczynam przygodę z programowaniem obiektowym.

Głównie chodzi mi o ocenę wydajnośći skryptu. - Nie wiem czy lepiej być stale połączonym z bazą czy co chwile otwierać nowe połączenia(tak jak w klasie).
W kodzie może być malutki bałagan ale wszyscy wiemy jak coś wygląda gdy robi się to po dniu pracy.

Funkcje:
-insert
-update
-select

Wszystko POWINNO chodzić sprawnie.


  1. class dataBase {
  2.  
  3. private $_host = null;
  4. private $_database = null;
  5. private $_username = null;
  6. private $_password = null;
  7.  
  8. public function __construct(){
  9. $nn = new Hconfig;
  10. $data = $nn->dbConf();
  11. $this->_host = $data['host'];
  12. $this->_database = $data['db'];
  13. $this->_username = $data['username'];
  14. $this->_password = $data['password'];
  15.  
  16. }
  17.  
  18. public function insert($table, $fields, $values, $params){
  19. $table = '`'.$table.'`';
  20. $fields = preg_replace('/\s+/', '', $fields);
  21. $fields = explode(',', $fields);
  22. $values = explode(',', $values);
  23. $cf = count($fields);
  24. $cv = count($values);
  25. if($cf != $cv) { echo 'Podano złe parametry';}
  26. for($i=0;$i<$cf;$i++){$qf .= '`'.$fields[$i].'`, ';}
  27. $qf = substr($qf,0,-2);
  28. for($i=0;$i<$cv;$i++){$vf .= ':'.$fields[$i].', ';}
  29. $vf = substr($vf,0,-2);
  30. $vfe = preg_replace('/\s+/', '', explode(',', $vf));
  31. $params = explode(',', $params);
  32. try{
  33. $pdo = new PDO('mysql:host='.$this->_host.';dbname='.$this->_database.'', ''.$this->_username.'', ''.$this->_password.'');
  34. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  35. $stmt = $pdo->prepare('INSERT INTO '.$table.' ('.$qf.') VALUES ('.$vf.')');
  36. for($i=0;$i<$cf;$i++) {
  37. $stmt->bindValue($vfe[$i], $values[$i], $params[$i]);
  38. }
  39. $status = $stmt->execute();
  40. return $status;
  41. $stmt -> closeCursor();
  42. unset($stmt);
  43. unset($pdo);
  44. }
  45. catch(PDOException $e){
  46. echo $e->getMessage();
  47. }
  48. }
  49.  
  50. public function update($table, $fields, $values, $params, $where){
  51. if(empty($where)) {$wh = '';} else {$wh = 'WHERE ('.$where.')';};
  52. $table = '`'.$table.'`';
  53. $fields = preg_replace('/\s+/', '', $fields);
  54. $fields = explode(',', $fields);
  55. $values = explode(',', $values);
  56. $cf = count($fields);
  57. $cv = count($values);
  58. if($cf != $cv) { echo 'Podano złe parametry';}
  59. for($i=0;$i<$cf;$i++){$qf .= '`'.$fields[$i].'`, ';}
  60. $qf = substr($qf,0,-2);
  61. for($i=0;$i<$cv;$i++){$vf .= ':'.$fields[$i].', ';}
  62. $vf = substr($vf,0,-2);
  63. $vfe = preg_replace('/\s+/', '', explode(',', $vf));
  64. for($i=0;$i<$cf;$i++){$ustring .= '`'.$fields[$i].'`='.$vfe[$i].', ';}
  65. $ustring = substr($ustring,0,-2);
  66. $params = explode(',', $params);
  67. try{
  68. $pdo = new PDO('mysql:host='.$this->_host.';dbname='.$this->_database.'', ''.$this->_username.'', ''.$this->_password.'');
  69. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  70. $stmt = $pdo->prepare('UPDATE '.$table.' SET '.$ustring.' '.$wh.'');
  71. for($i=0;$i<$cf;$i++) {
  72. $stmt->bindValue($vfe[$i], $values[$i], $params[$i]);
  73. }
  74. $status = $stmt->execute();
  75. return $status;
  76. $stmt -> closeCursor();
  77. unset($stmt);
  78. unset($pdo);
  79. }
  80. catch(PDOException $e){
  81. echo $e->getMessage();
  82. }
  83. }
  84.  
  85. public function select($from, $fields, $where, $sort){
  86. if(empty($where)) {$wh = '';} else {$wh = 'WHERE ('.$where.')';};
  87. if(empty($sort)) {$srt = '';} else {$srt = 'SORT BY ('.$sort.')';};
  88. $table = '`'.$table.'`';
  89. try{
  90. $pdo = new PDO('mysql:host='.$this->_host.';dbname='.$this->_database.'', ''.$this->_username.'', ''.$this->_password.'');
  91. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  92. $stmt = $pdo -> query('SELECT '.$fields.' FROM '.$from.' '.$wh.' '.$srt.'');
  93. return $stmt;
  94. $stmt -> closeCursor();
  95. unset($stmt);
  96. unset($pdo);
  97. }
  98. catch(PDOException $e){
  99. echo $e->getMessage();
  100. }
  101. }
  102. }


Podkreślam, że póki co w programowaniu obiektowym raczkuje... Przyjmuje na klatę całą krytykę i sugestie na które niecierpliwie czekam.


Przykład zastosowania:

  1. $posio = new dataBase;
  2. $test = $posio->insert('users', 'id, login, password, email', ', testlogin, testpassword, testmail', '1, 2, 2, 2');
  3. if($test > 0 ) { echo 'Dane zostały dodane'; }
phpion
1. Szkoda, że ograniczasz się jedynie do MySQL poprzez zastosowanie `. W przypadku użycia PostgreSQL otrzymasz błąd - tam kolumny escape'uje się za pomocą ".
2. Czy nie prościej do insert i update przekazać tablicę wartości na zasadzie klucz -> wartość, np:
  1. $obj->insert('tabela', array(
  2. 'pole1' => 'wartosc1',
  3. 'pole2' => 'wartosc2'
  4. ));

3. Składowe $_host, $_database itd. wydają mi się zbędne. Zamiast nich przetrzymywałbym całą tablicę $_config.
4. W każdej metodzie tworzysz na nowo obiekt PDO. Wyodrębnij to do osobnej metody connect.
5. Brakuje metody delete smile.gif
Posio
phpion
1. Czy ` i " są zbędne dla baz danych ? Jeśli tak na pewno troszkę to przestawię.
2. Racja -,- nie pomyślałem nad łatwiejszą i przyjemniejszą drogą ale obydwa rozwiązania działają prawidłowo
3. Zanim pomyślałem, że dane do bazy będę pobierał z klasy konfiguracji wszystkie dane dot. bazy wyglądały tak:

  1. private $_host = 'localhost';
  2. private $_database = 'exdb';
  3. private $_username = 'posio';
  4. private $_password = 'xx';

-> aby nie tracić czasu po prostu w funkcji __construct traktuje je danymi z tablicy.

4. To mnie najbardziej trapi. Gdzieś kiedyś rzucił mi się w oczy artykuł na temat tworzenia połączeń z bazą i ponoć każdorazowo tworząc nowe połączenie (wcześniej zamykając stare) zwiększamy bezpieczeństwo. Nie wiem na jakiej zasadzie ma to działać, możliwe że wprowadziło mnie to w błąd ale zostawiam to jeszcze do przedyskutowania nim wyodrębnie metode.
5. Rzeczywiście zapomniałem - napisze jeszcze dziś albo jak znajde troszkę wolnego czasu
Crozin
Jest jakiś sens wymyślać tutaj koło na nowo*? W dodatku dosyć kanciaste koło.

* a to tylko jeden przykład.
!*!
A nie lepiej byłoby robić coś takiego (zakładając że chcesz coś własnego):

  1. $getArt = new db(); // gdzie zawraca obiekt pdo, jako parametr konstruktora przekazać nazwę bazy
  2. $getArt->pdo-> setAttribute();
  3. $getArt->pdo-> prepare();


Tym sposobem:
1. Nie robisz jakiejś chorej nakładki na zapytania
2. Korzystasz bezpośrednio z PDO
Posio
Crozin
Niestety ale muszę się z tobą zgodzić. Nie ma sensu.

Ale w myśl że tworząc takie "kanciate koła" zdobywam doświadczenie i koła te będą coraz to bardziej okrągłe ... znajduje powoli sens...

Gdybym potrzebował tego do tworzenia aplikacji czy strony, wierz mi, że wpadłbym na to żeby poszukać czy ktoś przypadkiem już tego PORZĄDNIE nie zrobił ...

Nie zakładajmy że skrypt nadaje się do globalnego użycia etc. bo się nie nadaje. Nie jestem profesjonalistą i pewnie nigdy ni będę, opublikowałem swoją pracę ponieważ chcę się uczyć a jeśli nikt nie podpowie co mam poprawić, stoje w miejscu.

- Ty umieściłeś tylko uwagę, że coś co działa podobnie jest dostępne. To nie jest ocena ... (nie licząc kanciatego koła ;P)
Spawnm
W czym to:
  1. $stmt = $pdo->prepare('INSERT INTO '.$table.' ('.$qf.') VALUES ('.$vf.')');
  2. for($i=0;$i<$cf;$i++) {
  3. $stmt->bindValue($vfe[$i], $values[$i], $params[$i]);
  4. }
  5. $status = $stmt->execute();


jest lepsze od:
  1. $stmt = $pdo->prepare('INSERT INTO '.$table.' ('.$qf.') VALUES ('.$vf.')');
  2. $stmt->execute($args);

?

Klasa paskudnie napisana. Nie widzę jakiegoś sensowniejszego zastosowania.
!*!
Posio - wybacz że się wcinam, ale skoro już jesteśmy w temacie, łączenia się z bazą. Jakbyście rozwiązali połączenia w jednej aplikacji dla wielu baz danych? Np przystosowanie forum, podczas instalacji jest wybór bazy np. mysql, ta informacja zapisana jest w cfg, ale co dalej? W kodzie dać coś takiego:

  1. if(dane z cfg = 'mysql')
  2. {
  3. klasa do łączenia się z mysql
  4. }
  5. elseif(dane z cfg = 'mssql')
  6. {
  7. klasa do łączenia się z mssql
  8. }


Czy są inne sposoby na coś takiego?
Posio
!*! - Spoko

Spawnm - O PDO I OOP uczyłem się tylko z wikibooks, staram się robić tak jak oni naprowadzali co i tak mi w pełni nie wychodzi. No i... chyba w niczym nie jest lepsze
Crozin
@Posio: Teraz dopiero zauważyłem, że to wątek w dziale Oceny. wink.gif Nie mniej jednak jeżeli chcesz się uczyć to źle się za to zabierasz. Obierz sobie jakiś cel i go zrealizuj, np. portal a'la [tutaj jakiś popularny portal]. Dobierz sobie jakieś sprawdzone narzędzia (ogólny framework, orm, mailer, bibliotekę do przetwarzania grafiki itd. itp.) i przy ich pomocy wykonaj zadanie. Zdobędziesz nieco obycia z kodem, będziesz wiedział jak mniej-więcej powinno się coś projektować, żeby później dało się tego używać.
Posio
@Crozin

Wielkie dzięki za dobre porady, na pewno się zastosuje i spróbuje zrobić coś bardziej sensownego niż powyższa namiastka klasy.
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.