Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP/PDO] Problem w wykonywaniem zapytań
TrAvIkK
post 22.08.2007, 12:02:13
Post #1





Grupa: Zarejestrowani
Postów: 35
Pomógł: 0
Dołączył: 23.11.2006

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
SongoQ
post 22.08.2007, 12:31:06
Post #2





Grupa: Przyjaciele php.pl
Postów: 2 923
Pomógł: 9
Dołączył: 25.10.2004
Skąd: Rzeszów - studia / Warszawa - praca

Ostrzeżenie: (0%)
-----


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.


--------------------
Go to the top of the page
+Quote Post
TrAvIkK
post 22.08.2007, 14:56:17
Post #3





Grupa: Zarejestrowani
Postów: 35
Pomógł: 0
Dołączył: 23.11.2006

Ostrzeżenie: (0%)
-----


Nie wiedziałem o tym poprostu winksmiley.jpg
Chodzi Ci o bindParam ?

Ten post edytował TrAvIkK 22.08.2007, 14:56:48
Go to the top of the page
+Quote Post
NoiseMc
post 22.08.2007, 22:22:09
Post #4





Grupa: Zarejestrowani
Postów: 398
Pomógł: 10
Dołączył: 24.11.2004
Skąd: Łódź

Ostrzeżenie: (0%)
-----


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.


--------------------
Go to the top of the page
+Quote Post
TrAvIkK
post 22.08.2007, 22:50:02
Post #5





Grupa: Zarejestrowani
Postów: 35
Pomógł: 0
Dołączył: 23.11.2006

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 6.07.2025 - 00:16