Technologie programowania systemów internetowych Laboratorium 3 Laboratorium 3 – Wprowadzenie do PDO Ćwiczenie 1. PDO – nawiązanie połączenia z bazą danych W poniższym ćwiczeniu możesz wykorzystać jedną z dwóch baz danych: serwer MySQL lub bazę plikową SQLite. Stwórz w bazie danych przykładowe tabele ksiazki i wydawnictwa – użyj skryptu dołączonego do ćwiczenia (ksiazki.mysql.sql lub ksiazki.sqlite.sql): o jeśli chcesz użyć bazy MySQL dostarczonej z pakietem XAMPP, możesz skorzystać z narzędzia phpMyAdmin – http://localhost/phpmyadmin/; najpierw stwórz bazę danych o nazwie ksiazki, następnie wykonaj w niej skrypt SQL; o jeśli chcesz użyć bazy SQLite, możesz skorzytać z narzędzia SQLiteSpy – http://www.yunqa.de/delphi/doku.php/products/sqlitespy/index; najpierw stwórz nową bazę danych i zapisz do pliku ksiazki.db, następnie wykonaj skrypt SQL. Spróbuj nawiązać połączenie z bazą danych – kod w wersji dla MySQL: <?php try { $user = 'root'; $pass = ''; $dbh = new PDO('mysql:host=localhost;dbname=biblioteka', $user, $pass); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } Kod w wersji dla SQLite: <?php try { $dbh = new PDO('sqlite:ksiazki.db'); $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } Kod z kolejnych ćwiczeń będziemy umieszczać wewnątrz tego samego bloku try…catch, zaraz po utworzeniu obiektu $dbh. Strona 1 z 4 Technologie programowania systemów internetowych Laboratorium 3 Ćwiczenie 2. Obsługa prostych zapytań Wysłanie zapytania i wyświetlenie wyniku: $result = $dbh->query('SELECT * from wydawnictwa'); echo '<pre>'; foreach($result as $row) { print_r($row); } echo '</pre>'; Przyjrzyj się strukturze tablicy zawierającej pobrane dane (zmienna $row wyświetlona za pomocą print_r). Zmodyfikuj kod tak, by wyświetlał dane w tabeli HTML: echo '<table>'; echo '<tr><th>ID</td><th>Nazwa</th></tr>'; foreach($result as $row) { echo '<tr>'; echo '<td>' . $row['id'] . '</td>'; echo '<td>' . $row['nazwa'] . '</td>'; echo '</tr>'; } echo '</table>'; Zadanie 1. Poniżej listy wydawnictw wyświetl w tabelce dane o wszystkich książkach. Zapytanie powinno się odwoływać do obu tabel w bazie (ksiazki, wydawnictwa). Wyświetlona tabelka powinna zawierać kolumny: o ID książki, Tytuł, Autor, Nazwa wydawnictwa. Strona 2 z 4 Technologie programowania systemów internetowych Laboratorium 3 Ćwiczenie 3. Modyfikacja danych w bazie Stwórz nowy skrypt o nazwie dodajWydawnictwo.php. Skopiuj do niego kod nawiązujący połączenie z bazą danych. Po nawiązaniu połączenia, wewnątrz bloku try, dodaj kod tworzący nowy wiersz w tabeli wydawnictwa: $wydawnictwo = 'Kluwer'; $sql = "insert into wydawnictwa(nazwa) values('{$wydawnictwo}')"; $dbh->exec($sql); echo "Dodano wydawnictwo: {$wydawnictwo}"; Dodaj sprawdzanie identyfikatora nowoutworzonego wiersza: $id = $dbh->lastInsertId(); echo "Dodano wydawnictwo: ID={$id}, nazwa={$wydawnictwo}"; Czy metoda lastInsertId() zadziałała zgodnie z oczekiwaniami? W przypadku baz MySQL i SQLite powinna zadziałać prawidłowo. W przypadku baz PostgreSQL i Oracle należałoby dodatkowo podać jako argument nazwę sekwencji. Dla innych baz – należy sprawdzić w dokumentacji, jak dany system obsługuje pola automatycznie inkrementowane oraz jak użyć dla danej bazy metody lastInsertId(). Odśwież kilkakrotnie stronę, tak by dodać do bazy kilka wpisów z nazwą wydawnictwa „Kluwer”. Zadanie 2. Zmodyfikuj skrypt z ćwiczenia 3, tak by nazwę wydawnictwa pobierał z tablicy $_POST. Na stronie z listą wydawnictw i książek umieść formularz dodawania wydawnictwa z jednym polem: Nazwa wydawnictwa. Przesłanie formularza ma spowodować wywołanie skryptu dodajWydawnictwo.php i dodanie wiersza do tabeli wydawnictwa. Strona 3 z 4 Technologie programowania systemów internetowych Laboratorium 3 Zadanie 3. Ochrona przed SQL Injection Zastanów się, czy skrypt dodajWydawnictwo.php jest podatny na atak typu SQL Injection? Spróbujmy przeprowadzić atak – w formularzu dodawania wydawnictwa wpisz jako nazwę następujący tekst: '); delete from ksiazki where ('x'='x Co się stało przy próbie dodania książki? Zabezpiecz skrypt używając metody quote() z klasy PDO. Zadanie 4. Na stronie z listą wydawnictw umieść obok nazwy każdego z wydawnictw link Usuń. Kliknięcie na linku powinno spowodować usunięcie wydawnictwa z bazy. Pamiętaj o ochronie przed SQL Injection. Zadanie 5. Uzupełnij aplikację o dodawanie i usuwanie książek. Przy dodawaniu książki nazwę wydawnictwa użytkownik powinien wybrać z listy rozwijanej. Pamiętaj o ochronie przed SQL Injection. Zadanie 6. Wszędzie tam, gdzie zapytanie kierowane do bazy jest uzupełniane o parametry pochodzące z żądania HTTP, zamień zwykłe zapytania na preinterpretowane (Prepared Statement). Przykład użycia Prepared Statement: $sql = 'select * from students where group_id = ? and gpa > ?'; $ps = $dbh->prepare($sql); $ps->execute( array(8, 4.0) ); $result = $ps->fetchAll(); foreach($result as $row) { echo "ID: {$row['id']}. Name: {$row['surname']}<br>"; } Zwróć uwagę na to, że nie jest już konieczne użycie funkcji quote(). Strona 4 z 4