Kurs PDO - podpinanie parametrów cz.2

Wpis napisany 22 lutego 2009 w kategoriach: (x)HTML/CSS, PHP/MySQL, Techblog, Wszystkie | 15:20:39 | 1 komentarz

Witam wszystkich po dłuższej przerwie spowodowanej głównie moim lenistwem ;). Inaczej nie da się wytłumaczyć tego, że przez dwa tygodnie wolnego (ferie) nie napisałem nic na blogu. Dzisiaj jednak zamierzam dodać kolejny artykuł do serii na temat PDO. Z tego wpisu dowiecie się jak za pomocą podpinania zmiennych do kolumn pobierać dane z bazy.

Czytaj dalej »

Kurs PDO - podpinanie parametrów cz.1

Wpis napisany 26 grudnia 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 16:26:51 | 7 komentarzy

Dzisiejszy wpis będzie obejmował tematykę znaną już z serii na temat ADOdb. Dowiecie się w jaki sposób realizować podpinanie parametrów w PDO oraz na czym polegają różnice między obydwiema bibliotekami. Dla tych, którzy nie wiedzą co to jest, przedstawię także zasadę działania oraz powody dla których używa się tej funkcjonalności. Warto jedynie wspomnieć, że PDO obsługuje znacznie więcej możliwości związanych z podpinaniem parametrów.

Dlaczego stosować?

Podpinanie parametrów ma bardzo wiele zalet nad zwyczajnym filtrowaniem danych i podklejaniem ich do zapytań. Jedną z najważniejszych jest czytelność. Dzięki odpowiednim identyfikatorom wiemy, która zmienna pod jakie miejsce w zapytaniu trafia. Nie musimy się bawić w łączenie długich ciągów znaków, rzutowanie typów i setki filtrów, PDO zrobi to za nas samo. Osobiście znam pewną osobę która po prostu gubi się w tych wszystkich apostrofach gdy nadchodzi potrzeba dołączenia kilku zmiennych do zapytania, nawet bez filtrowania zmiennych!

Pomimo tego najważniejszą zaletą takiego działania jest zabezpieczenie przed ataki typu SQL Injection. Dane które wstawiamy do zapytań zawsze są filtrowane pod względem znaków niebezpiecznych dla bazy danych której używamy, ponadto PDO bierze pod uwagę typ danych który wysyłamy (jeżeli podamy jaki to typ).

Jak tego używać?

Jak dobrze dobrze zapewne pamiętacie (a jeżeli nie, to polecam ich ponowną lekturę) z poprzednich wpisów, wysyłanie zapytania pobierającego dane w PDO składa się z dwóch etapów:

  1. Przekazaniu zapytania do PDO::query()
  2. Pobranie danych przy pomocy zwróconego nam obiektu klasy PDOStatement

W przypadku podpinania parametrów także użyjemy klasy PDOStatement, jednak tym razem cała operacja będzie nieco bardziej skomplikowana. Pozwala to na zwiększenie możliwości, jednak znacznie zmniejsza wygodę użytkowania. Nic nie stoi na przeszkodzie, aby napisać sobie niewielką nakładkę dla ułatwienia niektórych operacji. Zapoznajmy się w takim razie z kolejnymi krokami, jakie należy wykonać:

  1. Przygotowanie zapytania przy pomocy PDO::prepare()
  2. Podpięcie parametrów przy pomocy obiektu klasy PDOStatement
  3. Wykonanie zapytania przy pomocy PDOStatement::execute()
  4. Pobranie danych z obiektu klasy PDOStatement()

PDO pozwala na podpinanie parametrów na dwa sposoby. Przed wykonaniem zapytania, przy pomocy metody PDOStatement::bindValue(), lub podczas wykonywania zapytania metodą PDOStatement::execute(). Ponadto biblioteka obsługuje dwa sposoby identyfikacji parametrów. Przy pomocy liczb oraz nazw.

PDO::bindValue()

W przypadku podpinania danych poprzez PDO::bindValue() uzyskujemy możliwość dokładnego określenia rodzaju danych, które wysyłamy do zapytania. Dokonujemy tego podczas przypisywania kolejnych zmiennych do identyfikatorów/liczb. Kilka przykładów:

 
$stmt =  $db->prepare('SELECT * FROM users WHERE id = ? AND password = ?');
$stmt -> bindValue(0, $_SESSION['user_id'], PDO::PARAM_INT); //Podpinamy zmienną $_SESSION['user_id'] do pierwszego znaku zapytania jako liczbę
$stmt -> bindValue(1, $_SESSION['password'], PDO::PARAM_STR, 32); //Podpinamy zmienną $_SESSION['password'] zamiast drugiego znaku zapytania jako 32 literowy ciąg znaków
$stmt->execute();
 

Przypadek z numerycznym umieszczaniem parametrów (ang. placeholders). Każdy parametr posiada swój numer według kolejności występowania znaków zapytania. Liczenie zaczynamy od jedynki (w przypadku używania metody PDOStatement::bindValue()).

 
$stmt =  $db->prepare('SELECT * FROM users WHERE id = :user_id AND password = :user_pass');
$stmt -> bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT); //Podpinamy zmienną $_SESSION['user_id'] do parametru o nazwie :user_id jako liczbę
$stmt -> bindValue(':user_pass', $_SESSION['password'], PDO::PARAM_STR, 32); //Podpinamy zmienną $_SESSION['password'] zamiast identyfikatora :user_pass jako 32 literowy ciąg znaków
$stmt->execute();
 

Przypadek z nazwami jako identyfikatory parametrów (ang. named parameters). Każdy parametr posiada swoją własną nazwę według której podpinane są wartości.

Warto wspomnieć jeszcze jednej funkcji do popinania parametrów - PDOStatement::bindParam(). Jedyna różnica w stosunku do PDOStatement::bindValue() jest taka, że zmienne przekazane jako parametry podpinane są przez referencję, co umożliwia wykonanie kilki podobnych zapytań zaraz po sobie, podobnie jak robiliśmy to w przypadku ADOdb. Wystarczy, że zmienimy wartość umieszczoną w zmiennej podpiętej do zapytania i ponownie wykonamy metodę execute().

 
$user = 'Klaus';
$players = $pdo -> prepare('SELECT * FROM players WHERE user = ?');
$players -> bindParam(1, $user);
 
 
$players -> execute();
$player = $players -> fetch();
echo $player['email'].'<br>';
$players -> closeCursor();
 
$user = 'PQA';
$players -> execute();
$player = $players -> fetch();
echo $player['email'].'<br>';
$players -> closeCursor();
 
$user = 'sss';
$players -> execute();
$player = $players -> fetch();
echo $player['email'].'<br>';
$players -> closeCursor();
 

Przekazywanie parametrów przy PDOStatement::execute()

Innym sposobem na umieszczenie wartości w zapytaniu jest podanie ich tablicy do metody PDOStatement::execute(). Jej indeksowanie zależy od wybranego przez nas sposobu identyfikowania parametrów. W przypadku parametrów z nazwami, używamy ich podobnie jak przy PDOStatement::bindValue(). Jeżeli natomiast numerujemy parametry, to ich indeks numeryczny w tablicy będzie odpowiadał kolejnym znakom zapytania.

 
$stmt = $db->prepare('SELECT * FROM users WHERE id = :user_id AND password = :user_pass');
$stmt->execute(array(
	':user_id' => $_SESSION['user_id'], 
	':user_pass' => $_SESSION['password']
));
 

Przypadek z nazwami jako identyfikatorami. Każdej nazwie podstawiana jest odpowiednia warość z tablicy przekazanej do PDOStatement::execute() o kluczu zależnym od identyfikatora parametru.

 
$stmt = $db->prepare('SELECT * FROM users WHERE id = ? AND password = ?');
$stmt->execute(array($_SESSION['user_id'],  $_SESSION['password']));
 

Przypadek ze znakami zapytania. Tym razem nie musimy podawać indeksów dla tablicy, ponieważ jest ona i tak domyślnie numerowana od zera. Osobiście używam właśnie tego sposobu ze względu na zwięzłość zapisu.

Dalej dane pobieramy już tak jak zwykle, przy pomocy metod PDOStatement::fetch(), PDOStatement::fetchAll() lub PDOStatement::fetchColumn(). Warto jedynie pamiętać, że PDOStatement zwraca jedynie wartość typu bool, która zawiera informację o powodzeniu wykonania zapytania. Wszelkie dane pobrane z bazy znajdują się nadal w obiekcie klasy PDOStatement na którym wykonaliśmy metodę execute().

 
$stmt = $db->prepare('SELECT * FROM users WHERE id = ? AND password = ?');
$stmt->execute(array($_SESSION['user_id'],  $_SESSION['password']));
foreach($stmt as $user)
{
    echo $user['login'].'<br>';
}
 

Zakończenie

To już wszystko co chciałem przedstawić w dzisiejszym wpisie. Następnym razem dowiemy się, w jaki sposób przy pomocy podpinania kolumn do zmiennych pobierać dane z bazy. Jeszcze tylko pytanie do czytelników: czy wpisy z serii na temat PDO są dla was przydatne? Jeżeli czegoś im brakuje, bardzo proszę o jakiś komentarz, chciałbym aby były one możliwie najlepszym źródłem wiedzy dla początkujących.

Zwracanie wartości przy include()?

Wpis napisany 28 listopada 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 19:38:57 | 21 komentarzy

Dzisiaj spotkałem się z bardzo ciekawym rozwiązaniem o którym wcześniej nie wiedziałem, dlatego postanowiłem podzielić się nim z innymi czytelnikami. Jednocześnie przepraszam za moją dość długą nieobecność i obiecuję poprawę w najbliższym czasie.

Wracając do tematu, czy wiecie że możliwe jest zwracanie wartości podczas wykonywania pliku PHP załadowanego przy include/require? Ciekaw jestem, ilu z was to wiedziało... Przykładowe kody wyglądają tak:

Czytaj dalej »

FETCH_ASSOC vs FETCH_NUM

Wpis napisany 06 października 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 19:54:18 | 9 komentarzy

Jak zapewne część z was wie (albo i nie) pracuję obecnie nad projektem zwanym Orodlin. W tymże właśnie zespole, ktoś niesamowicie genialny wpadł na pomysł używania numerycznego pobierania pól przy pomocy ADOdb (wszystko co w tym poście zostanie napisane, odnosi się także do PDO oraz mysql_fetch_num()). Istnieje pogląd, że numeryczne pobieranie pól jest szybsze...

W porządku. Mogę zrozumieć pewne względy wydajności przy pisaniu skryptów. Jednak nie potrafię znieść przedkładania wydajności kodu całkowicie ponad jego czytelność oraz elastyczność. Całą sytuację postaram się zobrazować na przykładzie jednego prostego kawałka kodu (przepisany na PDO dla lepszej czytelności):

Czytaj dalej »

Kurs PDO - CRUD (Create, Retrieve, Update, Delete)

Wpis napisany 29 września 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 16:19:30 | 3 komentarze

W dzisiejszym wpisie zamierzam kontynuować rozpoczęty ostatnio kurs PDO. Tym razem nauczymy się podstaw wstawiania, usuwania, pobierania i aktualizacji rekordów w bazie danych. Razem wszystkie te operacje nazywane są często CRUD (z angielskiego Create-Retrive-Update-Delete).

W przypadku dawnego sposobu wykonywania zapytań używanego w PHP, jedna funkcja (mysql_query) służyła do obsłużenia wszystkich ich rodzajów. W przypadku PDO pobieranie jest potraktowane w sposób szczególny, natomiast pozostałe zapytania wykonujemy przy pomocy jednej funkcji.

Czytaj dalej »

Kurs PDO - wprowadzenie

Wpis napisany 22 września 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 21:57:16 | 25 komentarzy

Tak jak zapowiadałem, w dzisiejszym wpisie zajmiemy się biblioteką PDO. Przy jej pomocy można w bardzo szybki i wygodny sposób pobrać dane z wielu popularnych baz danych (MSSQL, Firebird, MySQL, Informix, Oracle, ODBC, DB2, SQLite, PostgreSQL). Większość operacji poznanych przez nas wcześniej przy ADOdb możliwe jest do wykonania wzykorzystując jej możliwości, przy jednoczesnym znacznym przyspieszeniu i większej wygodzie użytkowania.

Dlaczego PDO?

PDO (PHP Data Objects) jest biblioteką która ma za zadanie wprowadzić jednolity sposób dostępu do baz danych. Poprzednie rozwiązanie było bardzo niedoskonałe. Nazwy funkcji dla każdej bazy były inne (mysq_connect, pg_connect), a możliwości dość mocno ograniczone (brak bindowania parametrów, zwracania całej tablicy czy obsługi wyjątków).

Obecnie problem ten rozwiązuje PDO, które jest dostępne domyślnie od PHP 5.1. Dostęp do każdej bazy danych jest realizowany przy pomocy tych samych funkcji i klas (typ bazy pobierany jest jedynie z konfiguracji), SQL Injection przestaje być problemem, a czas wykonywania jest znacznie mniejszy niż u konkurencyjnego ADOdb czy Creole.

Czytaj dalej »

ADOdb vs PDO

Wpis napisany 19 września 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 17:23:50 | 5 komentarzy

PDO jest kolejną biblioteką dostępu do bazy danych którą będę omawiał na łamach mojego bloga. W dzisiejszym wpisie chciałbym dość pokrótce omówić różnice w stosunku do ADOdb na temat którego pisałem we wcześniejszych postach.

Czytaj dalej »

Funkcje ADOdb i wykonywanie zapytań cz.3

Wpis napisany 12 września 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 15:14:03 | 5 komentarzy

W dzisiejszym wpisie omówię wykorzystanie cache w bibliotece ADOdb oraz moduł ADOdb C. Dowiecie się jak zapisać wynik zapytania przy pomocy ADOdb tak, aby ponowne pobieranie niezmienionych danych zajmowało jak najmniej czasu.

Cache - co to jest?

Cache jest to mechanizm, który umożliwia szybszy dostęp do danych przy pomocy zapisywania ich kopii w miejscu o szybszym czasie odczytu. Dzięki temu gdy dane się nie zmieniły, lub nie zależy nam na ich aktualności, nie musimy pobierać ich z bazy danych, nawiązując połączenie i wysyłając zapytanie. Wystarczy odczytać je ze zwykłego pliku zapisanego na dysku, który jest znacznie szybciej odczytywany, niż baza danych.

ADOdb i cache zapytań

Na samym początku chciałbym wypisać funckje obsługujące cache w ADOdb. Są to:

  • $db -> cacheExecute()
  • $db -> cacheGetAll()
  • $db -> cacheGetRow()
  • $db -> cacheGetOne()
  • $db -> cacheSelectLimit()

Czytaj dalej »

Funkcje ADOdb i wykonywanie zapytań cz.2

Wpis napisany 10 września 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 16:53:32 | 12 komentarzy

W dzisiejszej części artykułu na temat ADOdb poznamy funkcje, które są nieco rzadziej używane oraz nauczymy się korzystać z tak zwanych "prepared statements" - specjalnego sposobu przekazywania parametrów do zapytań SQL który ma za zadania zapobiec atakom typu SQL Injection. Oto lista funkcji, które dzisiaj poznamy:

  • $db -> AutoExecute()
  • $db -> Replace()

Czytaj dalej »

PHP 5.3/6.0 - robi się coraz ciekawiej cz.2

Wpis napisany 29 sierpnia 2008 w kategoriach: PHP/MySQL, Techblog, Wszystkie | 17:08:11 | 10 komentarzy

Dzisiaj napiszę o nieco częściej reklamowanej zmianie która dostanie się do nowych wersji PHP. Mowa tutaj o przestrzeniach nazw. Nigdy nie miałem okazji tworzyć czegoś poważnego w języku, który je obsługuje (uczę się podstaw Javy, poza tym pisałem kilka programów w C++), jednak postaram się opisać ich działanie najlepiej jak potrafię.

Funkcjonalność ta powstała, aby zapobiec powtarzaniu się nazw klas, funkcji i obiektów w różnych bibliotekach. Dzięki niej dwie klasy DB mogą istnieć w jednym projekcie. Obecnie stosuje się prosty trick, polegający na dodaniu nazwy biblioteki do nazwy klasy (np. ADOConnection, ADORecordSet). Nie jest to jednak wygodne, ponieważ wymusza na programiście wpisywanie tej długiej nazwy w każdym miejscu aplikacji... Naprawdę współczuję tym, którzy nie mają funkcji uzupełniania nazw w edytorze ;).

Czytaj dalej »

© Powered by JoggerPL and Albi