Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL]Czy da się używać dynamicznie funkcji SQL z biblioteką PDO?
Forum PHP.pl > Forum > Przedszkole
qrzysztof
Obecnie pracuję nad zmianą "sterownika" bazy danych z przestarzałego mysql na PDO.

Mam bardzo wygodną klasę DBManager do komunikacji z bazą, rozszerzającą klasę Database, która opiera się właśnie na "sterowniku" mysql. Chcę zmienić sterownik, modyfikując jedynie klasę Database.

Oto przykładowa metoda klasy DBManager:

  1. public function insertNews($title, $text, $link, $isCompleted) {
  2. $this->insert('t_newsy')->into('tytul', 'opis', 'link', 'ukonczony', 'data');
  3. $this->values($title, $text, $link, $isCompleted, Database::sqlMeta(SQL_NOW))->execute();
  4. return $this->getInsertId();
  5. }


Prawda, że wygodne?

Ale przy zmianie sterownika z mysql na PDO pojawił się problem. Czy mi się tylko wydaje, czy naprawdę nie można do obiektu PDOStatement przekazywać funkcji SQL? Czy specjalny typ parametru PDO::PARAM_SQL (gdyby taki istniał) rzeczywiście byłby takim problemem dla bezpieczeństwa? Przecież typ parametru jest w 100% pod kontrolą programisty, więc chyba może on określić sytuacje, w których spodziewa się kodu SQL (na przykład, że parametr zawierający kod SQL może pochodzić wyłącznie z interfejsu programistycznego, natomiast nie od użytkownika końcowego).

W mojej klasie DBManager (wersja oparta na rozszerzeniu mysql) można było przekazywać parametry zawierające kod SQL bez najmniejszego ryzyka narażenia się na atak typu SQL injection. Wystarczy spojrzeć na 3. linię zacytowanego kodu, a konkretnie na wyrażenie:

  1. Database::sqlMeta(SQL_NOW)


gdzie SQL_NOW jest po prostu stałą o wartości 'NOW()'.

Próba przekazania wartości 'NOW()' w każdy inny sposób zakończyłaby się zapisem łańcucha 'NOW()' w bazie.

Czy jest jakiś sposób, żeby przekazywać do PDO dynamicznie funkcje SQL? Czy muszę przebudowywać całą warstwę odpowiedzialną za komunikację z bazą danych? W takiej sytuacji będę chyba musiał rozważyć pozostanie przy przestarzałym mysl.
Damonsson
Możesz Musisz przecież bezpośrednio przekazać NOW(), bez bindowania. Pokaż, jak wygląda Twój sterownik, zakładam, że wystarczy dorobić do niego linijkę, która przekaże rzeczone NOW() bezpośrednio, bo teraz pewnie wszystko bindujesz.
qrzysztof
Mogę i tak też zrobiłem (kosztem kilku dodatkowych linii kodu). Zastanawia mnie tylko dlaczego twórcy PDO nie przewidzieli bindowania takich parametrów, skoro nie jest to w żaden sposób niebezpieczne.
Damonsson
No bo przecież bindowanie to tak prosto mówiąc, dodanie na sztywno apostrofów w około tego co bindujesz, żeby nie mogło wpłynąć na zapytanie. Więc do MySQL zawsze dotrze 'NOW()' zamiast NOW().
qrzysztof
Mnie by bardziej zależało na takim bindowaniu, że

1) Jeśli chcę bindować parametr jako łańcuch, to mam 100% pewności, że gdy w parametrze zostanie przekazany kod SQL, to nie dojdzie do jego interpretacji.
2) Jeśli chcę bindować parametr jako kod SQL, to mogę to zrobić.

Ale spoko. Rozszerzę sobie klasy PDO i PDOStatement i będę miał to, co chcę smile.gif
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.