Połączenie z bazą danych opisane zostało w części pierwszej. W tej części za pomocą PDO pobierzemy z bazy kilka rekordów, a w następnych częściach nauczymy się bindować zmienne i parametryzować zapytania, dodawać nowe rekordy i edytować już istniejące. Klasa PDO oferuje ku temu kilka naprawdę ciekawych rozwiązań, z którymi warto się zapoznać. Koncepcja pracy z PDO niejako powinna wymusić na nas zapomnienie o starszych standardach, gdy wszelkie zapytania do bazy wykonywało się za pomoca poleceń rodzaju query(). Tutaj będziemy to robić nieco inaczej i radzę się tego trzymać.
1. Ustawienie parametru - setAttribute()
W poprzednim artykule tryb raportowania błędów ustawiliśmy od razu w startowych parametrach połączenia, tym razem zrobimy to ianczej. Na samym początku pracy za pomocą metody $dbh->setAttribute() ustawimy ową opcję wymuszając na klasie rzucenie wyjątku w razie jakiegokolwiek problemu. Posłuży nam do tego metoda:
- $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- <?php
- $db_config = array(
- 'host' => 'localhost',
- 'port' => '3306',
- 'user' => 'root',
- 'pass' => 'password',
- 'db' => 'myDatabase',
- 'db_type' => 'mysql',
- 'encoding' => 'utf-8'
- );
- // próba połączenia
- try
- {
- $dsn = $db_config['db_type'] .
- ':host=' . $db_config['host'] .
- ';port=' . $db_config['port'] .
- ';encoding=' . $db_config['encoding'] .
- ';dbname=' . $db_config['db'];
- // tworzymy obiekt klasy PDO inicjując tym samym połączenie
- $dbh = new PDO($dsn, $db_config['user'], $db_config['pass']);
- // ustawiamy opcję PDO::ATTR_ERRMODE:
- $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- // w przypadku błędu, poniższe się już nie wykona:
- define('DB_CONNECTED', true);
- echo '<h1>Connection success!</h1>';
- // łapiemy ewentualny wyjątek:
- } catch(PDOException $e)
- {
- die('Unable to connect: ' . $e->getMessage());
- }
- ?>
2. Wysyłanie zapytania - query()
Wysłanie zapytania do bazy może odbyć się na dwa sposoby. Pierwszym jest standardowa metoda query(), która wysyła do bazy całe zapytanie. Jest to najkrótsza metoda do szybkiego pobrania rekordów. Tą metodę przedstawię jedynie w celu pokazania, że takowa jest. Podczas pracy nie będziemy z niej korzystać. Dlaczego? O tym za chwilę. Na początek pobierzmy kilka rekordów za pomocą zwykłego zapytania. Pobierzemy je za pomocą prostej metody:
- $dbh->query($zapytanie)
Testowa tabela
Na początek naszej zabawy z PDO stwórzmy sobie testową bazę, a w niej tabelę customers.Tabela może wyglądać tak jak na opisie poniżej - będę używał tej tabeli w dalszych przykładach, więc polecam stworzenie takowej:
Nazwa pola | Typ | Dodatkowe | Klucz obcy | Opis |
---|---|---|---|---|
customer_id | int(11) | PRIMARY KEY, AUTO_INCREMENT, NOT NULL | ID klienta | |
login | varchar(50) | NOT NULL | login | |
password | varchar(100) | NOT NULL | hasło | |
first_name | varchar(50) | NOT NULL | imię | |
last_name | varchar(50) | NOT NULL | nazwisko | |
varchar(100) | NOT NULL | |||
country | varchar(50) | NOT NULL | kraj | |
city | varchar(50) | NOT NULL | miasto | |
postal_code | varchar(10) | NOT NULL | kod pocztowy | |
address | varchar(250) | NOT NULL | adres | |
phone | varchar(25) | NOT NULL | telefon | |
created_at | int(11) | NOT NULL | czas utworzenia rekordu | |
updated_at | int(11) | NOT NULL | czas aktualizacji rekordu |
Załóżmy teraz, że naszym celem jest pobranie z tabeli wszystkich rekordów zawierających informacje o klientach. Korzystając z query() zapytanie wyglądać będzie następująco:
- $stmt = $dbh->query('SELECT * FROM customers');
Metoda $dbh->query() zwraca jako zbiór wyników zapytania obiekt klasy PDOStatement (stąd skrótowa nazwa obiektu - $stmt). Po obiekcie tym możemy się przelecieć jak po zwykłej tablicy:
1) za pomocą pętli foreach:
- foreach($stmt as $row)
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
2) za pomocą pętli while i metody $stmt->fetch():
- while($row = $stmt->fetch())
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
W obu powyższych rozwiązaniach wylistowana zostanie lista wszystkich użytkowników zapisanych w tabeli customers.
Przykład kodu:
- <?php
- // konfiguracja
- $conn_config = array(
- 'host' => 'localhost',
- 'port' => '3306',
- 'user' => 'root',
- 'pass' => 'password',
- 'db' => 'myDatabase',
- 'db_type' => 'mysql',
- 'encoding' => 'utf-8'
- );
- // próba połączenia
- try
- {
- $dsn = $conn_config['db_type'] .
- ':host=' . $conn_config['host'] .
- ';port=' . $conn_config['port'] .
- ';encoding=' . $conn_config['encoding'] .
- ';dbname=' . $conn_config['db'];
- $dbh = new PDO($dsn, $conn_config['user'], $conn_config['pass']);
- // ustawienie trybu raportowania błędów
- $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- define('DB_CONNECTED', true);
- echo '<h1>Connection success!</h1>';
- // zapytanie do bazy
- $stmt = $dbh->query('SELECT * FROM customers');
- // pobranie/wyświetlenie wyników
- while($row = $stmt->fetch())
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
- // łapiemy ewentualny wyjątek:
- } catch(PDOException $e)
- {
- die('Unable to connect: ' . $e->getMessage());
- }
Wynik:
- id: 0, imię: Jan, nazwisko: Kowalski
- id: 1, imię: Paweł, nazwisko: Nowak
- [...]
I na tym kończymy przygodę z używaniem query(), gdyż od tej chwili będziemy to robić inaczej, za pomocą metody prepare() i execute(), ale o tym za chwilę, ponieważ omówić musimy metodę fetch().
3. Pobieranie wierszy
a) Metoda fetch()
Jak już zapewne zauważyliśmy w kodzie, w PDO do pobrania rekordu służy metoda:
- $stmt->fetch()
Domyślnie pobiera ona wiersz jako tablicę asocjacyjną + index. Pozwala ona jednak na lekkie przekonfigurowanie swojej pracy, np. tak, aby zamiast tablicy zwracała nam obiekty, gdzie każdy wiersz (rekord) to oddzielny obiekt, a kolumny tabeli to jego właściwości.
Ustawienia typu zwracanych przez fetch() danych dokonujemy za pomocą metody:
- $stmt->setFetchMode($parametr);
lub
- $dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, $parametr);
gdzie $parametr może przybrać następujące wartości:
- PDO::FETCH_ASSOC - zwraca wiersz jako tablicę asocjacyjną, gdzie kluczem są nazwy kolumn
- PDO::FETCH_NAMED - podobnie jak FETCH_ASSOC, ale w przypadku kilku kolumn o tych samych nazwach zwraca tablicę ze wszystkimi wartosciami
- PDO::FETCH_NUM - zwraca wiersz jako tablicę z indeksem numerycznym
- PDO::FETCH_BOTH - zwraca wiersz jako tablicę z indeksem nazwowym oraz numerycznym (ta opcja jest domyślna)
- PDO::FETCH_OBJ - zwraca wiersz jako anonimowy objekt ustawiając jego właściwości na wartości kolumn
- PDO::FETCH_LAZY - połączenie FETCH_BOTH i FETCH_OBJ - tworzy właściwości obiektu nazywając właściwości obiektu jako nazwy kolumn lub za pomocą indeksu numerycznego, tak jak zostają wywołane
- PDO::FETCH_BOUND - zwraca wartości kolumn do zmiennych ustawionych za pomocą bindValue()
- PDO::FETCH_CLASS - zwraca wiersz jako instancję zadanej klasy, ustawiajac pola jako wlaściwości obiektu
- PDO::FETCH_INTO - aktualizuje obiekt zadanej klasy ustawiajac odpowiednie właściwości
Ustawienie danej opcji wpływa na metodę fetch() definiując rodzaj zwracanych przez nią danych od miejsca ustawienia opcji. Domyślnie ustawiona jest opcja FETCH_BOTH, czyli zwracamy tablicę asocjacyjną oraz z indeksem, co za tym idzie, do wiersza możemy dostać się za pomocą:
- $row['first_name']
ale możemy też i poprzez index numeryczny:
- $row[3]
W przypadku natomiast obiektu (PDO::FETCH_OBJ):
- $row->first_name
Parametr możemy też podać bezpośrednio jako argument metody fetch():
- while($row = $stmt->fetch(PDO::FETCH_ASSOC))
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
b) Metoda fetchAll()
Różnica pomiędzy metodą fetch(), a fetchAll() jest taka, iż o ile metoda fetch() pobiera za jednym razem jedynie jeden wiersz, na który ustawiony jest kursor, to metoda fetchAll() pobiera na raz do tablicy wszystkie wiersze. Przy dużej ilości wierszy może to więc powodować niemałe obciążenie.
Przyładowo, metody fetchAll() użyć możemy tak:
- $result = $stmt->fetchAll();
- foreach($result as $row)
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
c) Metoda fetchColumn()
Metoda fetchColumn() służy do zwrócenia wartości danej kolumny z wiersza. Jako parametr przyjmuje numer kolumny w zwracanym zapytaniu, licząc od 0. Brak podania parametru zwraca pierwszą kolumnę otrzymaną w wyniku zapytania.Przykład użycia:
- $stmt = $dbh->prepare("SELECT first_name, last_name, email FROM customers");
- $stmt->execute();
- echo 'imię: ' . $stmt->fetchColumn(0) .
- ', nazwisko:' . $stmt->fetchColumn(1) .
- ', email:' . $stmt->fetchColumn(2) .
- '<br />';
4. Wysyłanie zapytania - prepare() i execute()
I w tym miejscu doszliśmy do miejsca, gdzie żegnamy się już całkowicie z metodą query(). Jak widać na powyższym przykładzie użycia metody fetchColumn() nie została tam wykorzystana metoda query(), a metoda prepare(). Na czym polega różnica? Za pomocą:
- $stmt = $dbh->prepare($query);
nie wysyłamy całego zapytania od razu do bazy, a jedynie definiujemy jego szkielet.
Zapytanie takie wykonywane jest dopiero po wywołaniu metody:
- $stmt->execute();
Konstrukcja taka pozwala na kilka ciekawych zabiegów, takich jak parametryzowanie zapytań, które omówimy w następnym artykule, a także sprawia, iż oszczędzamy na czasie połączenia z serwerem bazy. W jaki sposób to działa i jakie jeszcze są z tego korzyści? O tym w następnym artykule. Na chwilę obecną jedynie zapamiętajmy, iż od tej chwili będziemy przygotowywać zapytania JEDYNIE za pomocą prepare(). Zapomnijmy o query().
5. Zwolnienie kursora - closeCursor()
Teraz bardzo ważna sprawa. Jak już napisałem wartością zwracaną przez zapytanie jest zbiór wyników będący obiektem klasy PDOStatement. Specyfika działania PDO pozwala na jednoczesną pracę jedynie na JEDNYM otwartym zbiorze. Czym jednak jest ten tzw. kursor? Otóż w momencie pobierania wyników ze zbioru, np. w pętli za pomocą metody fetch() - podczas każdego kolejnego przebiegu pętli ustawiany jest wskaźnik, czyli nasz kursor. Wskaźnik ten ustawiany jest na kolejny rekord ze zbioru - dzięki temu mozemy pobierać kolejne rekordy w pętlach. Chcąc więc pracować na kolejnym zbiorze wyników zwróconym przez kolejne zapytanie musimy ten kursor zwolnić i ustawić go z powrotem na pierwszy element z nowego zbioru wyników. Służy do tego metoda:
- $stmt->closeCursor():
którą wywołujemy ZAWSZE po skończonej pracy na danym zbiorze wyników.
Przykład użycia closeCursor():
- <?php
- // konfiguracja
- $conn_config = array(
- 'host' => 'localhost',
- 'port' => '3306',
- 'user' => 'root',
- 'pass' => 'password',
- 'db' => 'myDatabase',
- 'db_type' => 'mysql',
- 'encoding' => 'utf-8'
- );
- // próba połączenia
- try
- {
- $dsn = $conn_config['db_type'] .
- ':host=' . $conn_config['host'] .
- ';port=' . $conn_config['port'] .
- ';encoding=' . $conn_config['encoding'] .
- ';dbname=' . $conn_config['db'];
- $dbh = new PDO($dsn, $conn_config['user'], $conn_config['pass']);
- // ustawienie trybu raportowania błędów
- $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
- define('DB_CONNECTED', true);
- echo '<h1>Connection success!</h1>';
- // zapytanie do bazy
- $stmt = $dbh->prepare('SELECT * FROM customers');
- $stmt->execute();
- // pobranie/wyświetlenie wyników
- while($row = $stmt->fetch())
- {
- echo 'id: ' . $row['customer_id'] .
- ', imię:' . $row['first_name'] .
- ', nazwisko:' . $row['last_name'] .
- '<br />';
- }
- // zwolnienie kursora
- $stmt->closeCursor();
- unset($stmt);
- // [...] dalsze zapytania do bazy możliwe - kursor został zwolniony...
- // zamknięcie połączenia z bazą
- $dbh = null;
- // wyłapanie wyjątku w przypadku błędu połączenia z bazą
- } catch(PDOException $e)
- {
- die('Unable to connect: ' . $e->getMessage());
- }
- ?>
No i to w zasadzie tyle z podstaw odnośnie pobierania rekordów z bazy. W następnym artykule omówimy sobie tworzenie sparametryzowanych zapytań. Na koniec jeszcze dwie sprawy: jeśli chcemy sobie potestować rodzaje zwracanych przez fetch() danych, możemy sobie to zrobić za pomocą takiego wzoru:
- $stmt = $dbh->prepare('SELECT * FROM customers');
- $stmt->execute();
- echo('PDO::FETCH_ASSOC: ');
- echo('Wiersz indeksowany przez nazwę kolumny<br />');
- $result = $stmt->fetch(PDO::FETCH_ASSOC);
- echo_r($result);
- echo(' <br />');
- echo('PDO::FETCH_BOTH: ');
- echo('Wiersz indeksowany przez nazwę kolumny i indeks numeryczny <br />');
- $result = $stmt->fetch(PDO::FETCH_BOTH);
- echo_r($result);
- echo(' <br />');
- echo('PDO::FETCH_LAZY: ');
- echo('Wiersz zwracany jako obiekt - nazwy kolumn jako właściwości obiektu lub indeks numerowy <br />');
- $result = $stmt->fetch(PDO::FETCH_LAZY);
- echo_r($result);
- echo(' <br />');
- echo('PDO::FETCH_OBJ: ');
- echo('Wiersz zwracany jako obiekt - nazwy kolumn jako właściwości obiektu<br />');
- $result = $stmt->fetch(PDO::FETCH_OBJ);
- echo $result->LOGIN;
- echo(' <br />');
6. Zwracanie liczby rekordów - COUNT()
Drugą sprawą na koniec jest policzenie rekordów w tabeli.Zrobimy to w następujący sposób
- $stmt = $dbh->prepare('SELECT COUNT(customer_id) FROM customers');
- $stmt->execute();
- $result = $stmt->fetchColumn();
- $stmt->closeCursor();
- echo 'Liczba wierszy: ' . $result;
Oficjalny, pełny manual biblioteki PDO znajduje się tutaj: http://php.net/manual/en/book.pdo.php
Dzięki właśnie tego szukałem! Dobra robota będę na pewno dalej korzystał z twoich poradników! :)
OdpowiedzUsuńPhp Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download Now
Usuń>>>>> Download Full
Php Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download LINK
>>>>> Download Now
Php Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download Full
>>>>> Download LINK 1s
Ja pierdole zajebiscie qwa dzieki
OdpowiedzUsuńCo z tym encoding? Czy na pewno może być 'utf-8'? Bo niektóre źródła podają, że musi być 'utf8'...
OdpowiedzUsuńPhp Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download Now
OdpowiedzUsuń>>>>> Download Full
Php Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download LINK
>>>>> Download Now
Php Majster: [Php][Pdo] Podstawy Cz.2 - Pobieranie Rekordów Z Bazy >>>>> Download Full
>>>>> Download LINK