Nawi─ůzywanie po┼é─ůczenia z baz─ů danych MySQL

> Dodaj do ulubionych

Nale┼╝y u┼╝ywa─ç PDO i instrukcji gotowych (ang. prepared statement).

W PHP jest wiele mo┼╝liwo┼Ťci ┼é─ůczenia si─Ö z baz─ů danych MySQL. Najnowsz─ů i najlepsz─ů aktualnie metod─ů jest pos┼éugiwanie si─Ö obiektami PDO. PDO posiada sp├│jny interfejs do pracy z r├│┼╝nymi typami baz danych, jest konstrukcj─ů obiektow─ů oraz obs┼éuguje wiele nowych funkcji baz danych.

Instrukcje gotowe PDO pomagaj─ů unikn─ů─ç atak├│w typu SQL injection. Funkcja bindValue() uniemo┼╝liwia przeprowadzanie atak├│w polegaj─ůcych na natychmiastowym wykonaniu wstrzykni─Ötego szkodliwego kodu. (Nie jest ona niestety ca┼ékowicie bezpieczna, o czym mo┼╝na przeczyta─ç w portalu Stack Overflow). Kiedy┼Ť trzeba by┼éo wykonywa─ç skomplikowane manewry za pomoc─ů kombinacji ÔÇ×magicznych cytat├│wÔÇŁ. Dzi─Öki PDO wszystkie te sztuczki sta┼éy si─Ö zb─Ödne.

Przykład użycia PDO w PHP

<?php
try{
    // utworzenie nowego po┼é─ůczenia
    // w pierwszym parametrze pewnie trzeba b─Ödzie wpisa─ç localhost
    // Zwr├│─ç uwag─Ö na deklaracj─Ö zestawu znak├│w utf8mb4 ÔÇö jest to sygna┼é, ┼╝e zamierzamy u┼╝ywa─ç danych w formacie UTF-8. Czasami nie jest to konieczne, ale mo┼╝e zaoszcz─Ödzi─ç nam sporo k┼éopot├│w, gdy b─Ödziemy chcieli zapisywa─ç w bazie danych ┼éa┼äcuchy Unicode.  Zobacz te┼╝ Pu┼éapki na dole strony.
    // opis przkazywanych przez nas opcji PDO:
    // \PDO::ATTR_ERRMODE ÔÇö w┼é─ůcza wyj─ůtki dla b┼é─Öd├│w. Jest to ustawienie opcjonalne, ale bardzo przydatne.
    // \PDO::ATTR_PERSISTENT ÔÇö wy┼é─ůcza trwa┼ée po┼é─ůczenia, kt├│re czasami mog─ů powodowa─ç problemy ze wsp├│┼ébie┼╝no┼Ťci─ů. Zobacz Pu┼éapki na dole strony.
    $link = new \PDO(   'mysql:host=nazwa-hosta;dbname=baza-danych;charset=utf8mb4',
                        'nazwa-u┼╝ytkownika',
                        'hasło',
                        array(
                            \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
                            \PDO::ATTR_PERSISTENT => false
                        )
                    );
 
    $handle = $link->prepare('select Username from Users where UserId = ? or Username = ? limit ?');
 
    // B┼é─ůd PHP: bez PDO::PARAM_INT, PDO mo┼╝e umie┼Ťci─ç argument w cudzys┼éowie.  To z kolei mo┼╝e uszkodzi─ç zapytania MySQL, w kt├│rych liczby ca┼ékowite nie powinny by─ç w cudzys┼éowach.
    // Zobacz: https://bugs.php.net/bug.php?id=44639
    // Je┼Ťli nie masz pewno┼Ťci co do tego czy przekazywana warto┼Ť─ç jest liczb─ů ca┼ékowit─ů, u┼╝yj funkcji is_int().
    $handle->bindValue(1, 100, PDO::PARAM_INT);
    $handle->bindValue(2, 'Bilbo Baggins');
    $handle->bindValue(3, 5, PDO::PARAM_INT);
 
    $handle->execute();
 
    // Je┼Ťli trzeba pobra─ç bardzo du┼╝o wierszy, metoda fetchAll() mo┼╝e nadmiernie obci─ů┼╝a─ç system.
    // W takim przypadku mo┼╝na pos┼éu┼╝y─ç si─Ö metod─ů fetch(), a nast─Önie przegl─ůda─ç wiersze za pomoc─ů p─Ötli.
    // Ewentualnie można też zwracać tablicę i inne konstrukcje zamiast obiektów. Szczegółowe informacje znajdziesz w dokumentacji PDO.
    $result = $handle->fetchAll(\PDO::FETCH_OBJ);
 
    foreach($result as $row){
        print($row->Username);
    }
}
catch(\PDOException $ex){
    print($ex->getMessage());
}
?>

Pułapki

  • Brak parametru PDO::PARAM_INT przy wi─ůzaniu zmiennych ca┼ékowitoliczbowych mo┼╝e czasami spowodowa─ç umieszczenie ich przez PDO w cudzys┼éowie. W efekcie mo┼╝e doj┼Ť─ç do uszkodzenia niekt├│rych zapyta┼ä MySQL. Zobacz to zg┼éoszenie b┼é─Ödu PHP.
  • Je┼Ťli w ┼éa┼äcuchu po┼é─ůczenia zestaw znak├│w nie zostanie ustawiony na utf8mb4, to dane w formacie Unicode mog─ů zosta─ç nieprawid┼éowo zapisane w bazie danych, cho─ç wszystko zale┼╝y od konfiguracji.
  • Nawet je┼Ťli zostanie ustawiony zestaw znak├│w utf8mb4, nale┼╝y jeszcze dopilnowa─ç, by takie same ustawienie mia┼éy tabele bazy danych. O tym dlaczego u┼╝ywamy utf8mb4, a nie po prostu utf8 napiszemy w jednym z dalszych artyku┼é├│w.
  • W┼é─ůczenie trwa┼éych po┼é─ůcze┼ä mo┼╝e przyczyni─ç si─Ö do wyst─Öpowania dziwnych problem├│w ze wsp├│┼ébie┼╝no┼Ťci─ů. Nie jest to problem PHP, tylko aplikacji. Po┼é─ůcze┼ä trwa┼éych mo┼╝na bezpiecznie u┼╝ywa─ç pod warunkiem, ┼╝e ma si─Ö ┼Ťwiadomo┼Ť─ç konsekwencji.
  • W jednym wywo┼éaniu funkcji execute() mo┼╝na wykona─ç wi─Öcej ni┼╝ jedno zapytanie SQL, nale┼╝y tylko poszczeg├│lne instrukcje rozdzieli─ç ┼Ťrednikami. W PHP <= 5.3.10 nale┼╝y przy tym pami─Öta─ç o tym b┼é─Ödzie, kt├│rego nie naprawiono w wersji PHP dost─Öpnej w Ubuntu 12.04.

Autor: Alex Cabal

Źródło: http://phpbestpractices.org/

Tłumaczenie: Łukasz Piwko

Tre┼Ť─ç tej strony jest dost─Öpna na zasadach licencji CC BY-SA 3.0