Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP/PDO] Problem w wykonywaniem zapytań
Forum PHP.pl > Forum > PHP
TrAvIkK
Siemka winksmiley.jpg

Napisałem sobie aplikacje odpowiedzialną za bazę danych, jednak coś w niej niedziała.
Mianowicie, gdy wywołuję pierwsze zapytanie (procedura, która zwraca więcej niż 1 rekord) jest ok, ale gdy próbuje wykonać drugi raz inne zapytanie, które zwraca więcej niż 1 rekord, nie otrzymuje niczego.

Kod wygląda tak:

  1. <?php
  2. class MyPDO extends PDO 
  3. {
  4. /* Link z bazą danych */
  5. static $pdo;
  6.  
  7. /* Ilosc wykonanych zapytan */
  8. static $queries = 0;
  9.  
  10. /**
  11.  * Inicjalizacja połączenia z bazą danych przez PDO
  12.  */
  13. public function __construct()
  14. {
  15. self :: $pdo = new parent('mysql:host=localhost;dbname=db', 'root', '');
  16. }
  17.  
  18. /**
  19.  * Pobranie instancji obiektu bazy danych
  20.  *
  21.  * @return object
  22.  */
  23. static public function getInstance()
  24. {
  25. if (empty(self :: $pdo))
  26. {
  27. new MyPDO();
  28. }
  29.  
  30. return self :: $pdo;
  31. }
  32. }
  33.  
  34. class Statement extends PDOStatement 
  35. {
  36. /* Przygotowane zapytanie do bazy */
  37. private $preparedQuery;
  38.  
  39. /**
  40.  * Inicjalizacja obiektu
  41.  *
  42.  * @param string $prepared
  43.  * @param array $values
  44.  */
  45. public function __construct($prepared, $values)
  46. {
  47. $this -> preparedQuery = $prepared;
  48. $this -> getResult($values);
  49. }
  50.  
  51. /**
  52.  * Inicjalizacja zapytania do bazy
  53.  *
  54.  * @param array $values
  55.  */
  56. private function getResult($values)
  57. {
  58. $this -> preparedQuery -> execute($values);
  59. }
  60.  
  61. /**
  62.  * Pobranie danych z zapytania
  63.  *
  64.  * @return array
  65.  */
  66. public function getData()
  67. {
  68. $data = $this -> preparedQuery -> fetchAll();
  69. print_r($this -> errorInfo());
  70. return $data;
  71. }
  72. }
  73.  
  74. class DB extends MyPDO 
  75. {
  76. /**
  77.  * Sprawdza, czy w podanej tablicy nie wystepuje sql injection
  78.  *
  79.  * @param arrray $query
  80.  * @return bool
  81.  */
  82. static private function _injection(&$values)
  83. {
  84. $badWords = array('SELECT', 'INSERT', 'UPDATE', 'TRUNCATE', 'DELETE', 'UNION', '--');
  85.  
  86. for ($i = 0; $i < count($values); $i++)
  87. {
  88. $values[$i] = htmlentities($values[$i]);
  89. }
  90.  
  91. for ($i = 0; $i < count($values); $i++)
  92. {
  93. for ($j = 0; $j < count($badWords); $j++)
  94. {
  95. if (strpos($values[$i], $badWords[$j]))
  96. return true;
  97. }
  98. }
  99.  
  100. return false;
  101. }
  102.  
  103. /**
  104.  * Wykonuje podane zapytanie
  105.  *
  106.  * @param string $query
  107.  * @param array $values
  108.  * @return object
  109.  */
  110. static public function execute($query, $values)
  111. {
  112. if (!self :: _injection($values))
  113. {
  114. if (is_array($values))
  115. {
  116. parent :: $queries++;
  117.  
  118. $connection = parent :: getInstance();
  119. $sth = $connection -> prepare($query);
  120. return new Statement($sth, $values);
  121. }
  122. else 
  123. {
  124. throw new MyException('$values is not an array.', 0, __FILE__, __LINE__);
  125. }
  126. }
  127. else 
  128. {
  129. throw new MyException('SQL injection detected!', 0, __FILE__, __LINE__);
  130. }
  131. }
  132.  
  133. /**
  134.  * Zwraca wszystkie wyniki z podanego obiektu zapytania
  135.  *
  136.  * @param object $statement
  137.  * @return 2-d array
  138.  */
  139. static public function fetch($statement)
  140. {
  141. if (is_object($statement))
  142. {
  143. return $statement -> getData();
  144. }
  145. else 
  146. {
  147. throw new MyException('$statement is not an object', 0, __FILE__, __LINE__);
  148. }
  149. }
  150. }
  151. ?>


I potem odpowiednio:

  1. <?php
  2. $stmt = DB :: execute('CALL blablabla(?)', array(1));
  3. $data = DB :: fetch($stmt);
  4. ?>


No, i oczywiście print_r($this -> errorInfo()); wyrzuca pustego arraya, czyli nie ma błędu winksmiley.jpg
W ogóle czy takie rozwiązanie jest dobre? Tzn podzielić całość na 3 klasy, jedna od połączenia, druga od statement a trzecia do obsługi?
SongoQ
Moze troche nie na temat ale po co masz metode _injection ? przeciez wszytko to przez bind zrobisz, nie rozumiem po co na sile cos robic.
TrAvIkK
Nie wiedziałem o tym poprostu winksmiley.jpg
Chodzi Ci o bindParam ?
NoiseMc
Cytat
W ogóle czy takie rozwiązanie jest dobre? Tzn podzielić całość na 3 klasy, jedna od połączenia, druga od statement a trzecia do obsługi?

Mysle ze to co napisales to jest po prostu klasa z innymi nazwami metod ktore juz istnieja w samym PDO, nie wydaje mi sie zeby na PDO trzeba bylo cokolwiek jeszcze nakladac ... co do _injection wystarczy w zupelnosci jak bedziesz uzywal parametryzowanych zapytan (bindParam) i nikt nie ma prawa Ci wstrzyknac do zapytania zadnego zlosliwego kodu.
TrAvIkK
No ok, ale to dalej nie rozwiązuje problemu.
Gdy robię całość "nie obiektowo", czyli poprzez "normalne" wywoływanie metod PDO (czyli pierw prepare, execute, fetchAll) to przy kolejnym wywołaniu dostaje error, o niezbuforowanych zapytaniach.

Próbowałem już closeCursor, PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, próbowałem całość robić przez fetch(), nic nie pomaga.
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.