Jak skonfigurować i używać PDO do dostępu do bazy danych w systemie Linux

Jak skonfigurować i używać PDO do dostępu do bazy danych w systemie Linux

Cel

Dowiedz się, jak konfigurować i używać PDO do dostępu do bazy danych: od trybów błędów do pobierania metod.

Wymagania

  • Standardowa znajomość mysql i Mysql Klient wiersza poleceń;
  • Znajomość podstawowych koncepcji programowania obiektowego
  • Php> = 5.1
  • Mieć działającą bazę danych MySQL/Mariadb

Trudność

ŚREDNI

Konwencje

  • # - Wymaga podanych poleceń Linuksa, które można wykonać z uprawnieniami root
    bezpośrednio jako użytkownik root lub za pomocą sudo Komenda
  • $ - Wymaga, aby podane polecenia Linux zostały wykonane jako zwykły użytkownik niepewny

Wstęp

PDO to akronim dla Obiekty danych PHP: Jest to rozszerzenie PHP do interakcji z bazami danych za pomocą obiektów. Jedna z jego mocnych stron polega na tym, że nie jest ściśle powiązany z jakąś konkretną bazą danych: jego interfejs stanowi wspólny sposób dostępu do kilku różnych środowisk, między innymi:

  • Mysql
  • Sqlite
  • PostgreSQL
  • Microsoft SQL Server

Niniejszy przewodnik ma na celu zapewnienie całkiem pełnego przeglądu PDO, prowadząc czytelnika krok po kroku od ustanowienia połączenia z bazą danych, do wyboru najbardziej odpowiedniego trybu pobierania, pokazując, jak tworzyć przygotowane instrukcje i opisując możliwe tryby błędu.

Utwórz testową bazę danych i tabelę

Pierwszą rzeczą, którą zamierzamy zrobić, to stworzyć bazę danych dla tego samouczka:

Utwórz bazę danych solar_system; Przyznać wszystkie przywileje na Solar_System.* Do „testuser”@„localHost” zidentyfikowane przez „testPassword”; 
Kopiuj

Udzieliliśmy użytkownikowi testuser wszystkie przywileje na Układ Słoneczny baza danych, używając TestPassword jako hasło. Teraz utwórzmy tabelę i wypełnij ją niektórymi danymi (bez zamierzonej dokładności astronomicznej):

Użyj solar_system; Utwórz planety tabeli (id tinyint (1) unsigned not null auto_increment, klucz podstawowy (id), nazwa varchar (10) nie null, color varchar (10) nie null); Wstaw do planet (nazwa, kolor) wartości („ziemia”, „blue”), („mars”, „czerwony”), („Jupiter”, „dziwne”); 
Kopiuj

DSN: Nazwa źródła danych

Teraz, gdy mamy bazę danych, musimy zdefiniować DSN. DSN oznacza Nazwa źródła danych, i jest to w zasadzie zestaw informacji wymaganych do połączenia z bazą danych, reprezentowaną w postaci ciągu. Składnia może być inna w zależności od bazy danych, z którą chcesz się połączyć, ale ponieważ wchodzimy w interakcje z MySQL/Mariadb, zapewnimy:

  • Rodzaj sterownika do użycia do połączenia
  • Nazwa hosta komputera hostująca bazę danych
  • Port do użycia dla połączenia (opcjonalnie)
  • Nazwa bazy danych
  • Zacisk (opcjonalnie)

Format ciągu, w naszym przypadku byłby następujący (zamierzamy go przechowywać w $ dsn zmienny):

$ dsn = "mysql: host = localhost; port = 3306; dbname = solar_system; charset = utf8"; 
Kopiuj

Po pierwsze, dostarczyliśmy Prefiks bazy danych. W takim przypadku, ponieważ łączymy się z bazą danych MySQL/MariaDB, użyliśmy Mysql. Następnie oddzieliliśmy prefiks od reszty sznurka pod dwurścien i każda z pozostałych sekcji przez półkolis.

W następnych dwóch sekcjach określiliśmy Nazwa hosta maszyny, na której hostowana jest baza danych i Port użyć do połączenia. Jeśli ten ostatni nie zostanie podany, domyślnie zostanie użyte, co w tym przypadku jest 3306. Natychmiast po zapewnieniu Nazwa bazy danych, A po tym znak używać.

Tworzenie obiektu PDO

Teraz, gdy nasz DSN jest gotowy, zbudujemy Obiekt PDO. Konstruktor PDO bierze ciąg DSN jako pierwszy parametr, nazwę użytkownika w bazie danych jako drugi parametr, jego hasło jako trzecie i opcjonalnie tablica opcji jako czwarta:

$ options = [pdo :: attr_errmode => pdo :: errMode_Exception, pdo :: attr_default_fetch_mode => pdo :: fetch_assoc]; $ pdo = new pdo ($ dsn, „testuser”, „testPassword”, $ opcje); 
Kopiuj

Opcje można jednak określić również po skonstruowaniu obiektu za pośrednictwem SetAttribute () metoda:

$ pdo-> setAttribute (pdo :: attr_errmode, pdo :: errMode_Exception); 
Kopiuj

Ustawienie zachowania PDO na błędach

Rzućmy okiem na niektóre z dostępnych opcji PDO :: attr_errmode. Ta opcja jest naprawdę ważna, ponieważ definiuje zachowanie PDO w przypadku błędów. Możliwe opcje to:

PDO :: errmode_silent

To jest domyślne. PDO po prostu ustawi kod błędu i komunikat o błędzie. Można je odzyskać za pomocą Kod błędu() I errorInfo () metody.

PDO :: errMode_Exception

Moim zdaniem jest to zalecane. Dzięki tej opcji, oprócz ustawienia kodu błędu i informacji, PDO rzuci PDOException, które przełamią przepływ skryptu i jest to szczególnie przydatne w przypadku Transakcje PDO (Zobaczymy, jakie transakcje są później w tym samouczku).

PDO :: errMode_Warning

Dzięki tej opcji PDO ustawi kod błędu i informacje zgodnie z indeksowaniem PDO :: errmode_silent, ale również wyprowadzi OSTRZEŻENIE, które nie złamią przepływu skryptu.

Ustawienie domyślnego trybu pobierania

Kolejne ważne ustawienie można określić za pośrednictwem PDO :: default_fetch_mode. stały. Pozwala określić domyślną metodę pobierania do użycia podczas pobierania wyników z zapytania. Są to najczęściej używane opcje:

PDO :: fetch_both:

To jest domyślne. Z nim wynik pobrany przez zapytanie zostanie indeksowane zarówno według liczby całkowitych, jak i nazwy kolumny. Zastosowanie tego trybu pobierania podczas pobierania wiersza z tabeli planet dałoby nam ten wynik:

$ stmt = $ pdo-> zapytanie („Wybierz * z planet”); $ wyniki = $ stmt-> fetch (pdo :: fetch_both); 
Kopiuj
Tablica ([id] => 1 [0] => 1 [nazwa] => ziemia [1] => ziemia [kolor] => blue [2] => niebieski) 

PDO :: fetch_assoc:

Z tą opcją wynik zostanie przechowywany w tablica asocjacyjna w którym każdy klucz będzie nazwą kolumny, a każda wartość będzie odpowiednią wartością w wierszu:

$ stmt = $ pdo-> zapytanie („Wybierz * z planet”); $ wyniki = $ stmt-> fetch (pdo :: fetch_assoc);
Kopiuj
Tablica ([id] => 1 [nazwa] => ziemia [kolor] => niebieski) 

PDO :: fetch_num

Ten tryb pobierania zwraca pobierany wiersz do Tablica 0 indeksyjna:

Tablica ([0] => 1 [1] => ziemia [2] => niebieski) 

PDO :: fetch_column

Ta metoda pobierania jest przydatna podczas pobierania tylko wartości kolumny i zwróci wszystkie wyniki wewnątrz zwykłej, jednowymiarowej tablicy. Na przykład to zapytanie:

$ stmt = $ pdo-> zapytanie („Wybierz nazwę z planet”);
Kopiuj

Zwróciłby ten wynik:

Tablica ([0] => ziemia [1] => Mars [2] => Jowisz) 

PDO :: fetch_key_pair

Ta metoda pobierania jest przydatna podczas pobierania wartości zaledwie 2 kolumn. Zwróci wyniki w formie tablicy asocjacyjnej, w której wartości pobrane z bazy danych dla pierwszej określonej kolumny w zapytaniu będą używane jako klawisze tablicy, podczas gdy wartości pobrane dla drugiej kolumny będą reprezentować asocjację asocjacyjną Wartości tablicy:

$ stmt = $ pdo-> zapytanie („Wybierz nazwę, kolor z planet”); $ wynik = $ stmt-> fetchall (pdo :: fetch_key_pair); 
Kopiuj

Powróci:

Tablica ([ziemia] => blue [mars] => czerwony [Jupiter] => dziwne) 

PDO :: fetch_object:

Podczas korzystania z PDO :: fetch_object stałe, an Anonimowy obiekt zostanie utworzony dla każdego pobranego wiersza. Jego (publiczne) właściwości zostaną nazwane na podstawie kolumn, a wyniki zapytania zostaną wykorzystane jako ich wartości. Zastosowanie tego trybu pobierania do tego samego zapytania powyżej zwróciło nam wynik w formularzu:

$ wyniki = $ stmt-> fetch (pdo :: fetch_obj);
Kopiuj
Obiekt stdClass ([nazwa] => ziemia [kolor] => niebieski) 

PDO :: fetch_class:

Ten tryb pobierania, podobnie jak powyższy, przypisuje wartość kolumn do właściwości obiektu, ale w tym przypadku powinniśmy określić istniejącą klasę, której należy użyć do utworzenia obiektu. Pokazajmy to, najpierw stworzymy klasę:

klasa planeta private $ name; Prywatny kolor $; Public Function SetName ($ planet_name) $ this-> name = $ planet_name;  public funkcja setColor ($ planet_color) $ this-> color = $ planet_color;  public funkcja getName () return $ this-> nazwa;  funkcja publiczna getColor () return $ this-> kolor;  
Kopiuj

Proszę zignorować naiwność powyższego kodu i po prostu zauważ, że właściwości klasy planety są prywatny A klasa nie ma konstruktora. Teraz spróbujmy pobrać wyniki.

Podczas używania aportować() z PDO :: fetch_class Musisz użyć setfechmode () Metoda w obiekcie instrukcji przed próbą pobrania danych, na przykład:

$ stmt = $ pdo-> zapytanie („Wybierz nazwę, kolor z planet”); $ stmt-> setfetchMode (pdo :: fetch_class, „planet”);
Kopiuj

Zapewniliśmy stałą opcję pobierania PDO :: fetch_class Jako pierwszy argument metody setfetchMode () i nazwa klasy, która powinna być używana do utworzenia obiektu („planeta” w tym przypadku) jako drugi. Teraz biegamy:

$ planet = $ stmt-> fetch ();
Kopiuj

Należy stworzyć obiekt planety:

var_dump ($ planet);
Kopiuj
Obiekt planet ([name: planet: private] => ziemia [kolor: planet: private] => niebieski) 

Zwróć uwagę, w jaki sposób pobierane wartości wynikające z zapytania zostały przypisane do odpowiednich właściwości obiektu, nawet jeśli są one prywatne.

Przypisanie właściwości po budowie obiektu

Klasa Planet nie ma zdefiniowanego jawnego konstruktora, więc nie ma problemów przy przypisywaniu właściwości; Ale co, jeśli klasa miała konstruktor, w którym właściwość została przypisana lub manipulowana? Ponieważ wartości są przypisane przed wywołaniem konstruktora, zostałyby zastąpione.

PDO pomaga dostarczyć Fetch_props_late stała: podczas korzystania z niego wartości zostaną przypisane do właściwości Po Obiekt jest konstruowany. Na przykład:

klasa planeta private $ name; Prywatny kolor $; funkcja publiczna __Construct ($ name = moon, $ color = Gray) $ this-> name = $ name; $ this-> kolor = $ kolor;  public funkcja setName ($ planet_name) $ this-> name = $ planet_name;  public funkcja setColor ($ planet_color) $ this-> color = $ planet_color;  public funkcja getName () return $ this-> nazwa;  funkcja publiczna getColor () return $ this-> kolor; 
Kopiuj

Zmodyfikowaliśmy naszą klasę planet, zapewniając konstruktor, który przyjmuje dwa argumenty: pierwszy to nazwa A drugi jest kolor. Argumenty te mają odpowiednio wartość domyślną księżyc I szary: Oznacza to, że jeśli żadne wartości nie zostaną wyraźnie podane, będą to przypisane wartości domyślne.

W takim przypadku, jeśli nie używamy Fetch_props_late, Bez względu na wartości pobrane z bazy danych, właściwości będą zawsze miały wartości domyślne, ponieważ zostaną zastąpione po skonstruowaniu obiektu. Sprawdźmy to. Najpierw uruchamiamy zapytanie:

$ stmt = $ pdo-> query („Wybierz nazwę, kolor z solar_system gdzie nazwa =„ ziemia ””); $ stmt-> setfetchMode (pdo :: fetch_class, „planet”); $ planet = $ stmt-> fetch ();
Kopiuj

Następnie zrzucamy Planeta obiekt i sprawdź, jakie wartości mają jego właściwości:

var_dump ($ planet); Object (Planet)#2 (2) [„name”: „Planet”: private] => String (4) „Moon” [„Color”: „Planet”: private] => String (4) „Gray” 
Kopiuj

Zgodnie z oczekiwaniami wartości pobrane z bazy danych zostały zastąpione przez wartości domyślne. Teraz pokazujemy, w jaki sposób ten problem można rozwiązać za pomocą za pomocą Fetch_props_late (Zapytanie jest takie samo jak powyżej):

$ stmt-> setfetchMode (pdo :: fetch_class | pdo :: fetch_props_late, „planet”); $ planet = $ stmt-> fetch (); var_dump ($ planet); Object (Planet)#4 (2) [„name”: „planet”: private] => String (5) „Earth” [„Color”: „Planet”: private] => String (4) „niebieski” 
Kopiuj

Wreszcie otrzymaliśmy pożądane wyniki. Ale co, jeśli konstruktor klas nie ma wartości domyślnych i należy je dostarczyć ? Proste: możemy określić parametry konstruktora w formie tablicy jako trzeci argument, po nazwie klasy, w metodzie setfetchMode (). Na przykład, zmień konstruktor:

klasa planeta private $ name; Prywatny kolor $; funkcja publiczna __Construct ($ name, $ color) $ this-> name = $ name; $ this-> kolor = $ kolor;  […]
Kopiuj

Argumenty konstruktora są teraz obowiązkowe, więc uruchomilibyśmy:

$ stmt-> setfetchMode (pdo :: fetch_class | pdo :: fetch_props_late, „planet”, [„moon”, „grey”]);
Kopiuj

W takim przypadku dostarczone przez nas parametry służą jako wartości domyślne, potrzebne do zainicjowania obiektu bez błędów: zostaną zastąpione przez wartości pobrane z bazy danych.

Pobieranie wielu obiektów

Oczywiście możliwe jest pobranie wielu wyników jako obiektów, albo za pomocą aportować() Metoda w środku Pętla:

while ($ planet = $ stmt-> fetch ()) // rób rzeczy z wynikami 
Kopiuj

lub przez pobieranie wszystkich wyników jednocześnie. W takim przypadku, jak wspomniano powyżej, używając fetchall () Metoda, nie musisz określać trybu pobierania przed wywołaniem samej metody, ale w tej chwili ją nazywasz:

$ stmt-> fetchall (pdo :: fetch_class | pdo_fetch_props_late, „planet”, [„moon”, „grey”]); 
Kopiuj

PDO :: fetch_into

Dzięki temu zestawowi metody Fetch PDO nie utworzy nowego obiektu, zamiast tego zaktualizuje właściwości istniejącego, ale tylko wtedy, gdy są publiczny, lub jeśli używasz __ustawić Metoda magiczna wewnątrz obiektu.

Przygotowane vs bezpośrednie stwierdzenia

PDO ma dwa sposoby wykonywania zapytań: jeden to bezpośrednia, jednoetapowa droga. Drugi, bezpieczniejszy jest użycie przygotowane stwierdzenia.

Bezpośrednie zapytania

Korzystając z bezpośrednich zapytań, masz dwie główne metody: zapytanie() I exec (). Powrót poprzednie zwraca Pdostatemnt obiekt, którego można użyć, aby uzyskać dostęp do wyników za pośrednictwem aportować() Lub fetchall () Metody: Używasz go do instrukcji, która nie modyfikuje tabeli, takiej jak WYBIERAĆ.

Ten ostatni, zamiast tego zwraca liczbę wierszy, które zostały zmienione przez zapytanie: Używamy go do stwierdzeń, które modyfikują wiersze, jak WSTAWIĆ, USUWAĆ Lub AKTUALIZACJA. Bezpośrednie instrukcje mają być używane tylko wtedy, gdy nie ma zmiennych w zapytaniu i absolutnie ufasz, że jest bezpieczna i odpowiednio ucieknięta.

Przygotowane stwierdzenia

PDO obsługuje również dwustopniowe, przygotowane instrukcje: jest to przydatne podczas używania zmiennych w zapytaniu i ogólnie jest bezpieczniejsze, ponieważ jest to bardziej bezpieczne, ponieważ przygotowywać() Metoda wykona dla nas wszystkie niezbędne ucieczki. Zobaczmy, jak stosowane są zmienne. Wyobraź sobie, że chcemy wstawić właściwości obiektu planety do Planety tabela. Najpierw przygotujemy zapytanie:

$ stmt = $ pdo-> przygotuj („Wstaw do planet (nazwa, kolor) (?, ?) ”); 
Kopiuj

Jak powiedziano wcześniej, najpierw użyjemy przygotowywać() metoda, która przyjmuje zapytanie SQL jako argument, przy użyciu symboli zastępczych dla zmiennych. Teraz symbole zastępcze mogą mieć dwa rodzaje:

Udogodnienia zastępcze

Podczas używania ? Udanie zastępcze możemy uzyskać bardziej zwięzły kod, ale musimy dostarczyć wartości, które należy zastąpić w tej samej kolejności nazw kolumn, w tablicy dostarczonej jako argument do wykonać() metoda:

$ stmt-> execute ([$ planet-> nazwa, $ planet-> kolor]); 
Kopiuj

Nazwane zastępcze

Za pomocą Nazwane zastępcze, Nie musimy szanować określonego zamówienia, ale utworzymy bardziej pełnometrażowy kod. Podczas wykonywania wykonać() Metoda powinniśmy podać wartości w postaci tablica asocjacyjna w którym każdy klucz byłby nazwą używanego symboliki zastępczej, a powiązana wartość byłaby zastąpiona w zapytaniu. Na przykład powyższe zapytanie stało się:

$ stmt = $ pdo-> przygotuj („Wstaw do planet (nazwa, kolor) wartości (: nazwa,: color)”); $ stmt-> execute (['name' => $ planet-> nazwa, 'color' => $ planet-> kolor]); 
Kopiuj

Metody przygotowania i wykonania można użyć zarówno podczas wykonywania zapytań, które modyfikują lub po prostu pobierają dane z bazy danych. W pierwszym przypadku używamy metod pobierania powyżej do pobrania danych, podczas gdy w drugim możemy odzyskać liczbę dotkniętych wierszy za pomocą użycia Liczba wierszy() metoda.

Metody BindValue () i bindparam ()

Aby dostarczyć wartości, które należy zastąpić w zapytaniu, możemy również użyć bindValue () I bindparam () metody. Pierwszy wiąże wartość zmiennej podaną do powiązanego pozycji lub nazwanego symbolika zastępczego używana podczas przygotowywania zapytania. Korzystając z powyższego przykładu: zrobilibyśmy:

$ stmt-> bindValue ('name', $ planet-> nazwa, pdo :: param_str); 
Kopiuj

Wiązamy wartość $ Planet-> Nazwa do :nazwa symbol zastępczy. Zauważ, że używając zarówno metod BindValue (), jak i bindParam (), możemy określić, jako trzeci argument, typ zmiennej, stosując powiązaną stałą PDO, w tym przypadku PDO :: param_str.

Za pomocą bindparam (), Zamiast tego możemy powiązać zmienną z powiązanym symbolem zastępczym używanym podczas przygotowywania zapytania. Zauważ, że w tym przypadku zmienna jest związana odniesienie, a jego wartość zostanie zastąpiona tylko symbolami zastępczym wykonać() Metoda się nazywa. Składnia jest taka sama jak powyżej:

$ stmt-> bindParam ('name', $ planet-> nazwa, pdo :: param_str) 
Kopiuj

Związaliśmy zmienną $ planet-> do :nazwa symbol zastępczy, a nie jego obecna wartość! Jak wspomniano powyżej, konwersja zostanie wykonana tylko wtedy, gdy wykonać() Metoda zostanie wywołana, więc symbol zastępczy będzie zastąpiony wartością, którą zmienna ma w tym czasie.

Transakcje PDO

Transakcje stanowią sposób zachowania spójności podczas wydawania wielu zapytań. Wszystkie zapytania są wykonywane w „partii” i są zaangażowane w bazę danych tylko wtedy, gdy wszystkie z nich odniosą sukces. Transakcje nie będą działać we wszystkich bazach danych, a nie dla wszystkich SQL konstrukty, ponieważ niektóre z nich powodują i niejawne zatwierdzenie (pełna lista tutaj)

Z ekstremalnym i dziwnym przykładem wyobraź sobie, że użytkownik musi wybrać listę planet i za każdym razem, gdy przesyła nowy wybór, chcesz usunąć poprzedni z bazy danych. Co by się stało, gdyby usunięcie się powiedzie, ale nie wstawienie? Mielibyśmy użytkownika bez planet! Zazwyczaj w ten sposób wdrażane są transakcje:

$ pdo-> begintransaction (); spróbuj $ stmt1 = $ pdo-> exec („Usuń z planet”); $ stmt2 = $ pdo-> przygotuj („Wstaw do planet (nazwa, kolor) (?, ?) "); foreach ($ planet as $ planet) $ stmt2-> wykonuje ([$ planet-> getName (), $ planet-> getColor ()]); $ pdo-> commit (); catch (catch (catch ( PdoException $ e) $ pdo-> realback ();
Kopiuj

Przede wszystkim początekTransaction () Metoda obiektu PDO wyłącza autocommit zapytania, a następnie wewnątrz bloku próbnego, zapytania są wykonywane w poszukiwanej kolejności. W tym momencie, jeśli nie PDOException jest wychowywane, zapytania są popełnione za pomocą popełniać() Metoda, w przeciwnym razie przez Rollback () metoda, transakcje są powracane, a autokomit jest przywracany.

W ten sposób zawsze będzie konsekwencja podczas wydawania wielu zapytań. To całkiem oczywiste, że możesz użyć transakcji PDO tylko wtedy, gdy PDO :: attr_errmode jest ustawione na PDO :: errMode_Exception.

Powiązane samouczki Linux:

  • Rzeczy do zainstalowania na Ubuntu 20.04
  • Jak zmienić hasło użytkownika mariadb
  • Jak utworzyć stos lampy na bazie Dockera za pomocą Dockera na…
  • Instalacja Ampache Raspberry Pi
  • Wprowadzenie do automatyzacji, narzędzi i technik Linuksa
  • Instalacja OpenLitespeed WordPress
  • Rzeczy do zrobienia po zainstalowaniu Ubuntu 20.04 Focal Fossa Linux
  • Ubuntu 20.04 WordPress z instalacją Apache
  • Ubuntu 20.04: WordPress z instalacją Nginx
  • Zainstaluj MySQL na Ubuntu 20.04 LTS Linux