Kako raditi sa PDO? Kompletan vodič. Php oznaka Kako pravilno konfigurirati PDO vezu Pdo izraz za sql upit

  • Prevod

Mnogi PHP programeri su navikli da koriste mysql i mysqli ekstenzije za rad sa bazama podataka. Ali od verzije 5.1 u PHP-u postoji više zgodan način- PHP objekti podataka. Ova klasa, skraćeno nazvana PDO, pruža metode za rad sa objektima i pripremljenim iskazima koji će značajno poboljšati vašu produktivnost!

Uvod u PDO

“PDO – PHP Data Objects je sloj koji nudi univerzalna metoda rad sa više baza podataka."

On prepušta brigu o sintaktičkim karakteristikama različitih DBMS-ova programeru, ali čini proces prebacivanja između platformi mnogo manje bolnim. Često ovo zahtijeva samo promjenu niza povezivanja baze podataka.


Ovaj članak je napisan za ljude koji koriste mysql i mysqli kako bi im pomogli da pređu na moćniji i fleksibilniji PDO.

DBMS podrška

Ovo proširenje može podržati bilo koji sistem upravljanja bazom podataka za koji postoji PDO drajver. U vrijeme pisanja, dostupni su sljedeći drajveri:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB (FreeTDS/Microsoft SQL Server/Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Oracle Call Interface)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC i win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 i SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • PDO_4D (4D)
Međutim, nisu svi na vašem serveru. Listu dostupnih drajvera možete vidjeti ovako:
print_r(PDO::getAvailableDrivers());

Veza

Metode za povezivanje na različite DBMS-ove mogu se neznatno razlikovati. Ispod su primjeri povezivanja s najpopularnijim. Primijetit ćete da prva tri imaju identičnu sintaksu, za razliku od SQLite-a.
pokušajte ( # MS SQL Server i Sybase preko PDO_DBLIB $DBH = novi PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = novi PDO("sybase:host=$host ;dbname=$dbname", $user, $pass); # MySQL preko PDO_MYSQL $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = novi PDO("sqlite:my/database/path/database.db" catch(PDOException $e) ( echo $e->getMessage(); )
Obratite pažnju na blok try/catch - uvijek je vrijedno umotati sve vaše PDO operacije u njega i koristiti mehanizam izuzetaka (više o tome kasnije).

$DBH je skraćenica za “database handle” i koristit će se u cijelom članku.

Možete zatvoriti bilo koju vezu redefiniranjem njene varijable na null.
# zatvara vezu $DBH = null;
Više informacija o karakterističnim opcijama različitih DBMS-ova i metodama povezivanja na njih možete pronaći na php.net.

Izuzeci i PDO

PDO može izbaciti izuzetke na greške, tako da bi sve trebalo biti u bloku try/catch. Odmah nakon kreiranja veze, PDO se može staviti u bilo koji od tri načina greške:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Ali vrijedi napomenuti da će greška prilikom pokušaja povezivanja uvijek izazvati izuzetak.

PDO::ERRMODE_SILENT

Ovo je zadani način rada. Vjerovatno ćete koristiti otprilike istu stvar da uhvatite greške u mysql i mysqli ekstenzijama. Sljedeća dva načina su pogodnija za DRY programiranje.

PDO::ERRMODE_WARNING

Ovaj način će uzrokovati standardno upozorenje i omogućiti skriptu da nastavi izvršavanje. Pogodno za otklanjanje grešaka.

PDO::ERRMODE_EXCEPTION

U većini situacija, ova vrsta kontrole izvršavanja skripte je poželjnija. Izbacuje izuzetak, omogućavajući vam da pametno rukujete greškama i sakrijete osjetljive informacije. Kao, na primjer, ovdje:
# pokušajte povezati se sa bazom podataka ( $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) # Prokletstvo ukucao sam DELECT umjesto SELECT ("DELECT name FROM people") -> execute() catch(PDOException) (echo "Houston, imamo probleme."); "PDOErrors" .txt", $e->getMessage(), FILE_APPEND); )
Postoji sintaksička greška u SQL izrazu koja će baciti izuzetak. Možemo zabilježiti detalje greške u log fajlu i nagovijestiti korisniku na ljudskom jeziku da se nešto dogodilo.

Umetanje i ažuriranje

Umetanje novih podataka i ažuriranje postojećih podataka neke su od najčešćih operacija baze podataka. U slučaju PDO, ovaj proces se obično sastoji od dva koraka. (Sljedeći odjeljak je sve o UPDATE i INSERT)


Trivijalan primjer umetanja novih podataka:
# STH znači "Statement Handle" $STH = $DBH->prepare("INSERT INTO folks (first_name) values" ("Cathy")"); $STH->izvrši();
Zapravo, možete učiniti istu stvar s jednom exec() metodom, ali metoda u dva koraka daje sve prednosti pripremljenih izjava. Pomažu u zaštiti od SQL injekcija, pa ih ima smisla koristiti čak i za jednokratni upit.

Pripremljene izjave

Korištenje pripremljenih izjava jača zaštitu od SQL injekcija.

Prepared izraz je unaprijed kompajlirani SQL izraz koji se može izvoditi više puta slanjem samo različitih skupova podataka na poslužitelj. Dodatna pogodnost je nemogućnost izvođenja SQL injekcije kroz podatke koji se koriste u rezerviranim mjestima.

U nastavku su tri primjera pripremljenih izjava.
# bez rezerviranih mjesta - vrata za SQL injekcije su otvorena! $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti ($name, $addr, $city)"); # neimenovani čuvari mjesta $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (?, ?, ?)"); # imenovani čuvari mjesta $STH = $DBH->prepare("INSERT INTO folks (name, addr, city) vrijednosti (:name, :addr, :city)");
Prvi primjer je ovdje samo radi poređenja i treba ga izbjegavati. Razlika između bezimenih i imenovanih čuvara mjesta je u tome kako prosljeđujete podatke pripremljenim izjavama.

Neimenovani čuvari mjesta

# dodjeljuje varijable svakom čuvaru mjesta, sa indeksima od 1 do 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $city); # umetnite jedan red $name = "Daniel" $addr = "1 Wicked Way"; $city = "Arlington Heights"; $STH->izvrši(); # umetnite drugi red, sa drugačijim podacima $name = "Steve" $addr = "5 Circle Drive"; $city = "Šaumburg"; $STH->izvrši();
Ovdje postoje dva koraka. Na prvom dodjeljujemo varijable svim placeholderima (redovi 2-4). Zatim ovim varijablama dodjeljujemo vrijednosti i izvršavamo upit. Da biste poslali novi skup podataka, jednostavno promijenite vrijednosti varijabli i ponovo pokrenite zahtjev.

Ako vaš SQL izraz ima mnogo parametara, tada je dodjeljivanje varijable svakom vrlo nezgodno. U takvim slučajevima možete pohraniti podatke u niz i proslijediti ih:
# skup podataka koji ćemo umetnuti $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO ljudi (ime, adresa, grad) vrijednosti (?, ?, ?)"); $STH->izvrši($data);
$data će biti umetnuta umjesto prvog čuvara mjesta, $data umjesto drugog, itd. Ali budite oprezni: ako su vam indeksi pokvareni, ovo neće raditi.

Imenovani čuvari mjesta

# prvi argument je ime čuvara mjesta # obično počinje dvotočkom # iako radi bez njih $STH->bindParam(":name", $name);
Ovdje također možete proslijediti niz, ali on mora biti asocijativan. Ključevi bi trebali biti, kao što možete pretpostaviti, imena čuvara mjesta.
# podaci koje ubacujemo $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (:name, :addr, :city)"); $STH->izvrši($data);
Jedna od pogodnosti korištenja imenovanih čuvara mjesta je mogućnost umetanja objekata direktno u bazu podataka ako se imena svojstava podudaraju s imenima parametara. Na primjer, možete umetnuti podatke ovako:
# klasa za jednostavnu klasu objekata person ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a $this->city = $c ) # tako dalje... ) $cathy = new person("Cathy","9 Dark and Twisty","Cardiff"); # i evo zanimljivog dijela $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (:name, :addr, :city)"); $STH->execute((niz)$cathy);
Konvertovanje objekta u niz tokom execute() uzrokuje da se svojstva tretiraju kao ključevi niza.

Uzorkovanje podataka



Podaci se mogu preuzeti pomoću metode ->fetch(). Pre nego što ih pozovete, preporučljivo je da eksplicitno naznačite u kom obliku su vam potrebni. Postoji nekoliko opcija:
  • PDO::FETCH_ASSOC: vraća niz sa imenima kolona kao ključevima
  • PDO::FETCH_BOTH (zadano): vraća niz sa indeksima u obliku naziva kolona i njihovih serijskih brojeva
  • PDO::FETCH_BOUND: dodjeljuje vrijednosti stupaca odgovarajućim varijablama navedenim pomoću metode ->bindColumn().
  • PDO::FETCH_CLASS: dodjeljuje vrijednosti stupaca odgovarajućim svojstvima navedene klase. Ako ne postoji svojstvo za neki stupac, biće kreirano
  • PDO::FETCH_INTO: ažurira postojeću instancu navedene klase
  • PDO::FETCH_LAZY: kombinuje PDO::FETCH_BOTH i PDO::FETCH_OBJ
  • PDO::FETCH_NUM: vraća niz sa ključevima kao brojevima kolona
  • PDO::FETCH_OBJ: vraća anonimni objekat sa svojstvima koja odgovaraju imenima kolona
U praksi će vam obično trebati tri: FETCH_ASSOC, FETCH_CLASS i FETCH_OBJ. Da biste naveli format podataka, koristite sljedeću sintaksu:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Možete ga postaviti i direktno kada pozivate metodu ->fetch().

FETCH_ASSOC

Ovaj format stvara asocijativni niz sa imenima kolona kao indeksima. To bi trebalo biti poznato onima koji koriste mysql/mysqli ekstenzije.
# budući da je ovo običan upit bez čuvara mjesta, # možete odmah koristiti query() metodu $STH = $DBH->query("SELECT name, addr, city from folks"); # postavlja način preuzimanja $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] "\n" ;
Petlja while() će iterirati kroz cijeli rezultat upita.

FETCH_OBJ

Ova vrsta akvizicije podataka kreira instancu std klase za svaki red.
# kreiraj upit $STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); # biramo način preuzimanja $STH->setFetchMode(PDO::FETCH_OBJ); # ispisuje rezultat while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; )

FETCH_CLASS

Kada se koristi fetch_class, podaci se zapisuju u instance navedene klase. U ovom slučaju, vrijednosti se dodjeljuju svojstvima objekta PRIJE pozivanja konstruktora. Ako svojstva s nazivima koji odgovaraju imenima stupaca ne postoje, bit će kreirana automatski (sa javnim opsegom).

Ako vaši podaci zahtijevaju obaveznu obradu odmah nakon što su primljeni iz baze podataka, mogu se implementirati u konstruktoru klase.

Na primjer, uzmimo situaciju u kojoj trebate sakriti dio adrese stanovanja osobe.
class secret_person ( public $name; javni $addr; javni $city; javni $other_data; funkcija __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> addr $this->other_data = $other);
Prilikom kreiranja objekta, sva mala latinična slova moraju biti zamijenjena sa x. hajde da proverimo:
$STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); while($obj = $STH->fetch()) ( echo $obj->addr; )
Ako adresa u bazi podataka izgleda kao '5 Rosebud', onda će izlaz biti '5 Rxxxxxx'.

Naravno, ponekad ćete htjeti da se konstruktor pozove PRIJE dodjeljivanja vrijednosti. PDO dozvoljava i ovo.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "tajna_osoba");
Sada kada ste završili prethodni primjer dodatna opcija(PDO::FETCH_PROPS_LATE), adresa se neće mijenjati, jer se ništa ne dešava nakon upisivanja vrijednosti.

Konačno, ako je potrebno, možete proslijediti argumente konstruktoru direktno prilikom kreiranja objekta:
$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));
Možete čak proslijediti različite argumente svakom objektu:
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // uradi nešto $i++; )

Druge korisne metode

Iako ovaj članak ne može (i ne pokušava da pokrije) svaki aspekt rada sa PDO-om (to je ogroman modul!), sljedećih nekoliko karakteristika ne može biti izostavljeno bez spominjanja.
$DBH->lastInsertId();
Metoda ->lastInsertId() vraća id posljednjeg umetnutog zapisa. Vrijedi napomenuti da se uvijek poziva na objektu baze podataka (koji se u ovom članku naziva $DBH), a ne na objektu s izrazom ($STH).
$DBH->exec("IZBRIŠI IZ ljudi GDJE 1"); $DBH->exec("SET time_zone = "-8:00"");
Metoda ->exec() se koristi za operacije koje ne vraćaju nikakve podatke osim broja zapisa na koje utiču.
$safe = $DBH->quote($nesigurno);
Metoda ->quote() postavlja navodnike u nizove podataka tako da ih je sigurno koristiti u upitima. Korisno ako ne koristite pripremljene izjave.
$rows_affected = $STH->rowCount();
Metoda ->rowCount() vraća broj zapisa koji su učestvovali u operaciji. Nažalost, ova funkcija nije radila sa SELECT upitima do PHP 5.1.6. Ako nije moguće ažurirati PHP verziju, broj zapisa se može dobiti na sljedeći način:
$sql = "IZABIR BROJ(*) OD ljudi"; if ($STH = $DBH->query($sql)) ( # provjeri broj zapisa if ($STH->fetchColumn() > 0) ( # izvrši potpunu selekciju ovdje jer su podaci pronađeni! ) else ( # ispisati poruku da nisu pronađeni podaci koji zadovoljavaju zahtjev) )

Zaključak

Nadam se da će ovaj materijal pomoći nekima od vas da pređu sa mysql i mysqli ekstenzija.

meta tag ključne riječi primjer (4)

Target

Kako ja vidim, vaš cilj u ovom slučaju je dvostruk:

  • kreirati i održavati jednokratnu/ponovnu upotrebu veze za svaku bazu podataka
  • provjerite je li veza ispravno konfigurirana

Rješenje

$provider = function() ( $instance = novi PDO("mysql:......;charset=utf8", "korisničko ime", "lozinka"); $instance->setAttribute(PDO::ATTR_ERRMODE, PDO: :ERRMODE_EXCEPTION $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $fabrika = nova StructureFactory($provider);

Zatim u drugom fajlu ili ispod u istom fajlu:

$something = $factory->create("Nešto"); $foobar = $factory->create("Foobar");

Sama fabrika bi trebala izgledati otprilike ovako:

Class StructureFactory ( zaštićena $provider = null; zaštićena $veza = null; javna funkcija __construct (poziv $provider) ( $this->provider = $provider; ) javna funkcija create($name) ( if ($this->connection = == null) ( $this->connection = call_user_func($this->provider); ) vrati novo $name($this->connection) )

Na ovaj način možete imati centraliziranu strukturu koja osigurava da se veza kreira samo kada je to potrebno. To bi takođe olakšalo proces jedinično testiranje i usluga.

Dobavljač će u ovom slučaju biti pronađen negdje tokom faze pokretanja. Ovaj pristup će također dati jasnu lokaciju na kojoj možete definirati konfiguraciju koju koristite za povezivanje na DB.

Imajte na umu da ovo krajnje pojednostavljen primjer. Možda biste željeli pogledati i sljedeća dva videa:

Također, toplo preporučujem čitanje odgovarajućeg vodiča o korištenju PDO-a (postoji loš dnevnik vodiča na mreži).

S vremena na vrijeme vidim pitanja o povezivanju na bazu podataka.
Većina odgovora nije kako ja to radim, ili jednostavno ne mogu tačno odgovoriti. Anyway; Nikada nisam razmišljao o tome jer način na koji to radim funkcionira za mene.

Ali evo jedne lude misli; Možda sve ovo radim pogrešno, i ako je tako; Zaista bih želeo da znam kako da se pravilno povežem sa bazom podataka MySQL podaci With koristeći PHP i PDO i učiniti dostupnim.

Evo kako ja to radim:

Prvo, evo moje strukturu fajla (skraćeno) :

Public_html/ * index.php * inicijalizirati/ -- load.initialize.php -- configure.php -- sessions.php

index.php
Na samom vrhu zahtevam("initialize/load.initialize.php"); ,

load.initialize.php

# konfiguracije stranice zahtijevaju("configure.php"); # povezivanje sa bazom podataka require("root/somewhere/connect.php"); // ova datoteka je smještena izvan public_html radi bolje sigurnosti. # uključuju klase foreach (glob("assets/classes/*.class.php") kao $class_filename)( include($class_filename); ) # uključuju funkcije foreach (glob("assets/functions/*.func.php") kao $func_filename)(include($func_filename); ) # upravljati sesijama require("sessions.php");

Znam da postoji bolji ili ispravniji način uključivanja časova, ali ne sjećam se šta je to bilo. Još nisam imao vremena da to ispitam, ali mislim da je bilo nešto sa automatskim učitavanjem. tako nešto...

configure.php
Ovdje u suštini samo premošćujem neke php.ini-properties i napraviti neke druge globalne postavke za stranicu

connect.php
Postavio sam vezu sa klasom tako da mogu i druge klase proširiti ovo...

Klasa connect_pdo ( zaštićena $dbh; javna funkcija __construct() ( pokušaj ( $db_host = " "; // ime hosta $db_name = " "; // ime baze podataka $db_user = " "; // korisničko ime $user_pw = " "; // lozinka $con = novi PDO("mysql:host=".$db_host."; dbname=".$db_name, $db_user, $user_pw $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $con->exec("SET CHARACTER SET utf8" // vrati sve sql zahtjeve kao UTF-8 ) catch (PDOException $err) ( echo "bezopasna poruka o grešci ako veza ne uspije"; $err->getMessage()); .
"; file_put_contents("PDOErrors.txt",$err, FILE_APPEND); // upiši neke detalje u dnevnik grešaka izvan public_html die(); // prekinuti vezu ) ) javna funkcija dbh() (vrati $this->dbh ) ) # stavite obrađivač baze podataka u var za lakši pristup $con = new connect_pdo();

Ovo je mjesto gdje zaista vjerujem da postoji prostor za velika poboljšanja jer sam nedavno počeo da učim OOP i koristim PDO umjesto mysql-a.
Zato sam samo pratio nekoliko tutorijala za početnike i isprobao različite stvari...

sessions.php
Osim rukovanja normalnim sesijama, također inicijaliziram neke klase u sesiji ovako:

If (!isset($_SESSION["sqlQuery"]))( session_start(); $_SESSION["sqlQuery"] = novi sqlQuery(); )

Dakle, ova klasa je dostupna svuda. Ovo možda nije baš dobra praksa(?)...
U svakom slučaju, ovo je ono što mi ovaj pristup omogućava da radim svuda:

Echo $_SESSION["sqlQuery"]->getAreaName("county",9); // izlazi: Aust-Agder (ime županije s tim ID-om u bazi podataka)

U mom klasa sqlQuery koji proširuje moj Klasa connect_pdo , imam javnu funkciju getAreaName koja upravlja upitom u mojoj bazi podataka.
Mislim da je prilično uredno.

Radi kao šarm
Tako da ja to u osnovi radim.
Također, kad god trebam da preuzmem nešto iz svog DB-a iz klase, radim nešto slično ovome:

$id = 123; $sql = "IZABERITE bilo šta IZ MyTable WHERE id = :id"; $qry = $con->prepare($sql); $qry -> bindParam(":id", $id, PDO::PARAM_INT); $qry -> izvršiti(); $get = $qry->fetch(PDO::FETCH_ASSOC);

Zato što ubacujem vezu u varijablu unutra connect_pdo.php, samo referenciram i spreman sam. Radi. Dobivam očekivane rezultate...

Ali bez obzira na ovo; Zaista bih vam bio zahvalan ako biste mi rekli da odem odavde. Umjesto toga morao bih promijeniti oblasti koje bih mogao ili trebao promijeniti radi poboljšanja itd...

Zaista želim da učim...

$dsn = "mysql:host=ime_vašeg_hosta;dbname=vaše_db_name_ovdje"; // definiramo ime hosta i ime baze podataka $username = "vi"; // definiramo korisničko ime $pwd="vaša_lozinka"; // probaj lozinku ( $db = novi PDO($dsn, $username, $pwd); ) catch (PDOException $e) ( $error_message = $e->getMessage(); echo "ovo se prikazuje jer je pronađena greška "; izlaz(); )

Nedavno sam sam došao do sličnog odgovora/pitanja. Evo šta sam uradio, ako nekoga zanima:

args = func_get_args();

) javna funkcija __call($method, $args) (if (prazno($this->db)) ($Ref = new \ReflectionClass("\PDO"); $this->db = $Ref->newInstanceArgs($ this->args ) return call_user_func_array(array($this->db, $method), $args));

Da biste ga pozvali, trebate samo promijeniti ovu liniju:

$DB = nova \Library\PDO(/* normalni argumenti */);

I tip nagoveštaja ako ga koristite (\Library\PDO$DB).

Ovo je zaista slično prihvaćenom odgovoru i vašem; međutim, ima značajnu prednost. Uzmite u obzir ovaj kod:

$DB = nova \Library\PDO(/* args */); $STH = $DB->prepare("SELECT * FROM users WHERE user = ?"); $STH->izvrši(niz(25)); $User = $STH->fetch();

Iako može izgledati kao običan PDO (izmijenjen je samo od strane te \Library\), on zapravo ne inicijalizira objekt sve dok ne pozovete prvu metodu, koja god da je. To ga čini optimiziranijim jer je kreiranje PDO objekta malo skupo. Ovo je transparentna klasa, ili ono što se zove Ghost, forma. Možete tretirati $DB kao običnu PDO instancu, proslijediti je okolo, raditi iste operacije, itd.

Predlažem da ne koristite $_SESSION za globalni pristup vašoj DB konekciji. Možete učiniti jednu od nekoliko stvari (u redu najgore za najbolje

  • praktičar):
  • Pristup $dbh koristeći globalni $dbh unutar vaših funkcija i klasa

    Koristite singleton registar i pristupite mu globalno, na primjer:

    $registry = MyRegistry::getInstance(); $dbh = $registry->getDbh();

    Dodajte rukovalac baze podataka klasama koje su mu potrebne:

Međutim, malo je napredniji i zahtijeva više "ožičenja" bez okvira. Stoga, ako je injekcija zavisnosti previše složena za vas, koristite singleton registar umjesto zbirke globalnih varijabli.

Pruža metode za pripremu izraza i rad sa objektima koji vas mogu učiniti produktivnijim!

Uvod u PDO

"PDO - PHP Data Objects je sloj pristupa bazi podataka koji pruža objedinjene metode za pristup različitim bazama podataka."

Ne oslanja se na specifičnu sintaksu baze podataka i omogućava vam da se lako prebacite na drugu vrstu baze podataka i platformu jednostavnom promjenom niza veze u većini slučajeva.

Ova lekcija nije opis procesa rada SQL. Namijenjen je onima koji koriste ekstenzije mysql ili mysqli da im pomogne da pređu na moćniji i prenosiviji PDO.

Podrška za baze podataka

Ekstenzija podržava bilo koju bazu podataka za koju postoji PDO drajver. Upravljački programi su trenutno dostupni za sljedeće tipove baza podataka:

  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Oracle Call Interface)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC i win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 i SQLite 2)
  • PDO_4D (4D)

Da bi sistem funkcionisao, dovoljno je instalirati samo one drajvere koji su zaista potrebni. Listu drajvera dostupnih na sistemu možete dobiti na sljedeći način:

Print_r(PDO::getAvailableDrivers());

Veza

Različite baze podataka mogu imati malo različite metode povezivanja. Metode za povezivanje sa nekoliko popularnih baza podataka prikazane su u nastavku. Primijetit ćete da su prva tri identična jedna drugoj, a samo SQLite ima specifičnu sintaksu.


pokušajte ( # MS SQL Server i Sybase sa PDO_DBLIB $DBH = novi PDO("mssql:host=$host;dbname=$dbname, $user, $pass"); $DBH = novi PDO("sybase:host=$host ;dbname=$dbname, $user, $pass"); # MySQL sa PDO_MYSQL $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = novi PDO("sqlite:my/database/path/database.db" catch(PDOException $e) ( echo $e->getMessage(); )

Obratite pažnju na blok probaj/uhvati- uvijek trebate omotati PDO operacije u blok probaj/uhvati i koristite mehanizam izuzetaka. Obično je napravljena samo jedna veza, naš primjer pokazuje višestruke veze za prikaz sintakse. $DBH sadrži ručku baze podataka i koristit će se u cijelom našem vodiču.

Možete zatvoriti bilo koju vezu postavljanjem ručke na null.

# Zatvorite vezu $DBH = null;

Možete saznati više o specifičnim opcijama i nizovima veze za različite baze podataka iz dokumenata na PHP.net.

Izuzeci i PDO

PDO može koristiti izuzetke za obradu grešaka. To znači da sve PDO operacije moraju biti zatvorene u blok probaj/uhvati. PDO može izbaciti tri nivoa grešaka, nivo kontrole grešaka se bira postavljanjem atributa načina kontrole grešaka za deskriptor baze podataka:

$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Bez obzira na postavljeni nivo kontrole, greška veze uvijek izaziva izuzetak i stoga uvijek treba biti zatvorena u bloku probaj/uhvati.

PDO::ERRMODE_SILENT

Nivo kontrole grešaka je podešen prema zadanim postavkama. Na ovom nivou greške se generišu po istom principu kao i kod ekstenzija mysql ili mysqli. Druga dva nivoa kontrole grešaka su prikladnija za DRY (Ne ponavljaj se) stil programiranja.

PDO::ERRMODE_WARNING

Na ovom nivou kontrole grešaka, generišu se standardna PHP upozorenja i program može da nastavi sa izvršavanjem. Ovaj nivo je pogodan za otklanjanje grešaka.

PDO::ERRMODE_EXCEPTION

Ovaj nivo kontrole grešaka treba koristiti u većini situacija. Izuzeci se generiraju kako bi se pažljivo rukovali greškama i sakrili podaci koji bi mogli pomoći nekome da hakuje vaš sistem. Ispod je primjer koji pokazuje prednosti izuzetaka:

# Pokušajte se spojiti na bazu podataka ( $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) # Pogrešno kucanje DELECT umjesto SELECT ("DELECT name FROM people"); " , $e->getMessage(), FILE_APPEND);

Ovdje postoji namjerna greška u naredbi SELECT. Ovo će izazvati izuzetak. Izuzetak će poslati opis greške u datoteku dnevnika i prikazati poruku korisniku.

Umetanje i ažuriranje podataka

Umetanje novih podataka ili ažuriranje postojećih podataka jedna je od najčešće korištenih uobičajenih operacija baze podataka. Kada se koristi PDO, on se razlaže u dvije faze. Sve što je opisano u ovom poglavlju odnosi se na obje operacije. UPDATE I INSERT.


Evo primjera najčešće korištene vrste umetanja podataka:

# STH je "ručnik stanja" $STH = $DBH->prepare("INSERT INTO folks (first_name) values" ("Cathy")"); $STH->izvrši();

Naravno, ovu operaciju možete izvesti pomoću metode exec(), a broj poziva će biti za jedan manji. Ali bolje je koristiti duži metod da biste iskoristili prednosti pripremljenih izraza. Čak i ako ih namjeravate koristiti samo jednom, pripremljeni izrazi će vam pomoći da se zaštitite od napada na vaš sistem.

Pripremljeni izrazi

Pripremljeni izrazi su unaprijed kompajlirani SQL izrazi koji se mogu izvršiti mnogo puta slanjem samo podataka na poslužitelj. Imaju dodatnu prednost automatskog popunjavanja šablona podacima u obliku zaštite od napada putem priloga SQL koda.

Možete koristiti pripremljene izraze uključivanjem predložaka u svoj SQL kod. Ispod su 3 primjera: jedan bez predložaka, jedan s neimenovanim predlošcima, jedan s imenovanim predlošcima.

# bez šablona - otvoren za napade SQL injekcije! $STH = $DBH->("INSERT INTO ljudi (ime, adresa, grad) vrijednosti ($name, $addr, $city)"); # neimenovani šabloni $STH = $DBH->("INSERT INTO folks (ime, adresa, grad) vrijednosti (?, ?, ?); # imenovani šabloni $STH = $DBH->("INSERT INTO folks (ime) , addr , city) vrijednost (:name, :addr, :city)");

Trebali biste izbjegavati korištenje prve metode. Izbor imenovanih ili neimenovanih obrazaca utječe na to kako postavljate podatke za ove izraze.

Neimenovani šabloni

# dodjeljuje varijable svakom šablonu, indeksirane od 1 do 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $city); # Umetnite jedan red $name = "Dima" $addr = "Lizjukova ulica."; $city = "Moskva"; $STH->izvrši(); # Umetni još jedan red $name = "Senja" $addr = "Komunistički ćorsokak"; $city = "Petar"; $STH->izvrši();

Operacija se odvija u dvije faze. U prvom koraku, varijable se dodeljuju predlošcima. Zatim se varijablama dodjeljuju vrijednosti i izraz se izvršava. Da biste poslali sljedeći dio podataka, morate promijeniti vrijednosti varijabli i ponovo pokrenuti izraz.

Izgleda malo glomazno za izraze sa puno parametara? Svakako. Međutim, ako su vaši podaci pohranjeni u nizu, onda će sve biti vrlo kratko:

# Podaci za umetanje $data = array("Monya", "Forget-Me-Not Avenue", "Zakutaysk"); $STH = $DBH->("INSERT INTO folks (ime, adresa, grad) vrijednosti (?, ?, ?)"); $STH->izvrši($data);

Podaci u nizu se zamjenjuju u šablone redoslijedom kojim se pojavljuju. $data ide na prvi šablon, $data na drugi, itd. Međutim, ako je niz indeksiran drugačijim redoslijedom, takva operacija neće biti izvedena ispravno. Morate osigurati da redoslijed obrazaca odgovara redoslijedu podataka u nizu.

Imenovani predlošci

Evo primjera korištenja imenovanog šablona:

# Prvi argument funkcije je ime imenovanog šablona # Imenovani šablon uvijek počinje dvotočkom $STH->bindParam(":name", $name);

Možete koristiti prečice, ali one rade sa povezanim nizovima. primjer:

# Podaci za umetanje $data = array("name" => "Michelle", "addr" => "Kuznechny Lane", "city" => "Cnjkbwf"); # Skraćenica $STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)"); $STH->izvrši($data);

Vaši ključevi tablice ne zahtijevaju dvotočku, ali i dalje moraju odgovarati imenima šablona. Ako koristite niz nizova, možete iterirati kroz njega i jednostavno pozvati izvršiti za svaki skup podataka.

Još jedna lijepa karakteristika imenovanih predložaka je mogućnost umetanja objekata direktno u vašu bazu podataka kada se svojstva i nazivi polja poklapaju. primjer:

# Jednostavna klasa objekta person (javno $name; public $addr; public $city; funkcija __construct($n,$a,$c) ( $this->name = $n; $this->addr = $a; $ this->city = $c ) # etc. ... ) $cathy = nova osoba("Katya","Lenjin Avenue","Mozhaisk"); # Izvrši: $STH = $DBH->("INSERT INTO folks (name, addr, city) value (:name, :addr, :city)"); $STH->execute((niz)$cathy);

Pretvaranje tipa objekta u niz V izvršiti uzrokuje da se svojstva tretiraju kao ključevi niza.

Prijem podataka


Za dobijanje podataka koristi se metoda identifikatora stanja ->dohvati(). Prije pozivanja metode dohvati() morate reći PDO-u kako ćete dohvatiti podatke iz baze podataka. Možete odabrati sljedeće opcije:

  • PDO::FETCH_ASSOC: vraća niz indeksiran imenima stupaca
  • PDO::FETCH_BOTH (zadano): vraća niz indeksiran imenima i brojevima stupaca
  • PDO::FETCH_BOUND: Dodjeljuje vrijednosti vaših stupaca skupu varijabli koristeći metodu ->bindColumn()
  • PDO::FETCH_CLASS: dodjeljuje vrijednosti stupaca svojstvima imenovane klase ako odgovarajuće svojstvo ne postoji, kreira se
  • PDO::FETCH_INTO: ažurira postojeću instancu imenovane klase
  • PDO::FETCH_LAZY: kombinacija PDO::FETCH_BOTH/PDO::FETCH_OBJ, kreira imena varijabli objekata onako kako se koriste
  • PDO::FETCH_NUM: vraća niz indeksiran brojevima stupaca
  • PDO::FETCH_OBJ: vraća anonimni objekt s imenima svojstava koja odgovaraju imenima stupaca

U stvarnosti, osnovne situacije se rješavaju korištenjem tri opcije: FETCH_ASSOC, FETCH_CLASS I FETCH_OBJ. Za postavljanje metode ekstrakcije podataka:

$STH->setFetchMode(PDO::FETCH_ASSOC);

Takođe možete postaviti metodu preuzimanja podataka direktno u pozivu metode ->dohvati().

FETCH_ASSOC

Ovaj tip preuzimanja podataka kreira asocijativni niz indeksiran imenima stupaca. To bi trebalo biti prilično poznato onima koji koriste ekstenzije mysql/mysqli. Uzorak uzorka podataka:

$STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); # Postavite način preuzimanja podataka $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] "\n" ;

Ciklus dok nastavlja iterirati kroz rezultat uzorka red po red dok ne završi.

FETCH_OBJ

Sa ovom vrstom preuzimanja podataka kreira se objekt klase std za svaki red primljenih podataka:

$STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); # Postavite način preuzimanja podataka $STH->setFetchMode(PDO::FETCH_OBJ); # prikaži rezultat while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; )

FETCH_CLASS

Sa ovom vrstom ekstrakcije, podaci se postavljaju direktno u klasu koju odaberete. Prilikom upotrebe FETCH_CLASS svojstva vašeg objekta se postavljaju PRIJE pozivanja konstruktora. Ovo je veoma važno. Ako svojstvo koje odgovara imenu kolone ne postoji, tada će se takvo svojstvo kreirati (kao javnosti) za vas.

To znači da ako je podatcima potrebna transformacija nakon preuzimanja iz baze podataka, vaš objekat to može učiniti automatski čim se kreira.

Na primjer, zamislite situaciju u kojoj adresa mora biti djelomično skrivena za svaki unos. Zadatak možemo izvršiti manipuliranjem svojstvom u konstruktoru:

Class secret_person (javno $name; javni $addr; javni $city; javni $other_data; funkcija __construct($other = "") ( $this->address = preg_replace("//", "x", $this-> adresa $this->other_data = $other);

Jednom kada se podaci ekstrahuju u klasu, svi znakovi malih slova a-z u adresi će biti zamijenjeni znakom x. Sada, korištenjem klase i dohvaćanjem podataka, transformacija se događa potpuno transparentno:

$STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); while($obj = $STH->fetch()) ( echo $obj->addr; )

Ako je adresa bila 'Lenjinski prospekt 5' vidjet ćete 'Lxxxxxxxxxx xx-x 5'. Naravno, postoje situacije u kojima želite da se konstruktor pozove prije dodjeljivanja podataka. PDO ima sredstva za implementaciju ovoga:

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "tajna_osoba");

Sada, kada ponovite prethodni primjer sa podešenim načinom rada PDO::FETCH_PROPS_LATE adresa neće biti skrivena pošto je konstruktor pozvan i svojstva su dodeljena.

Ako trebate, možete proslijediti argumente konstruktoru prilikom izdvajanja podataka u objekt:

$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));

Ako trebate proslijediti različite podatke konstruktoru za svaki objekt, možete postaviti način preuzimanja podataka unutar metode donesi:

$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // radi stvari $i++)

Neke druge korisne metode

Budući da se PDO ne može u potpunosti opisati u kratkom članku, predstavit ćemo nekoliko korisnih metoda za izvođenje osnovnih operacija.

$DBH->lastInsertId();

Metoda ->lastInsertId() uvijek se poziva od strane ručke baze podataka (ne ručke stanja) i vraća vrijednost automatski povećanog ID-a posljednjeg umetnutog reda za datu vezu.

$DBH->exec("IZBRIŠI IZ ljudi GDJE 1"); $DBH->exec("SET time_zone = "-8:00"");

Metoda ->exec() koristi se za razne pomoćne operacije.

$safe = $DBH->quote($nesigurno);

Metoda ->citat() nizove kvota tako da se mogu koristiti u upitima. Ovo je vaša rezerva u slučaju da se pripremljeni izrazi ne koriste.

$rows_affected = $STH->rowCount();

Metoda ->rowCount() vraća vrijednost cijeli broj, koji označava broj redova koji se obrađuju operacijom. U najnovijoj verziji PDO-a, prema izvještaju o grešci (http://bugs.php.net/40822), ova metoda ne radi s izrazima SELECT. Ako imate problema i ne možete ažurirati PHP, broj redova možete dobiti na sljedeći način:

$sql = "IZABIR BROJ(*) OD ljudi"; if ($STH = $DBH->query($sql)) ( # Provjerite broj redova if ($STH->fetchColumn() > 0) ( # Ovdje bi trebao biti SELECT kod) else ( echo "Postoje nema redova koji odgovaraju upitu." ; ) )

Nadam se da vam se dopala lekcija!

  • Prevod

Mnogi PHP programeri su navikli da koriste mysql i mysqli ekstenzije za rad sa bazama podataka. Ali od verzije 5.1 u PHP-u postoji pogodniji način - PHP Data Objects. Ova klasa, skraćeno nazvana PDO, pruža metode za rad sa objektima i pripremljenim iskazima koji će značajno poboljšati vašu produktivnost!

Uvod u PDO

“PDO – PHP Data Objects je sloj koji nudi univerzalan način rada sa više baza podataka.”

On prepušta brigu o sintaktičkim karakteristikama različitih DBMS-ova programeru, ali čini proces prebacivanja između platformi mnogo manje bolnim. Često ovo zahtijeva samo promjenu niza povezivanja baze podataka.


Ovaj članak je napisan za ljude koji koriste mysql i mysqli kako bi im pomogli da pređu na moćniji i fleksibilniji PDO.

DBMS podrška

Ovo proširenje može podržati bilo koji sistem upravljanja bazom podataka za koji postoji PDO drajver. U vrijeme pisanja, dostupni su sljedeći drajveri:
  • PDO_CUBRID (CUBRID)
  • PDO_DBLIB (FreeTDS / Microsoft SQL Server / Sybase)
  • PDO_FIREBIRD (Firebird/Interbase 6)
  • PDO_IBM (IBM DB2)
  • PDO_INFORMIX (IBM Informix Dynamic Server)
  • PDO_MYSQL (MySQL 3.x/4.x/5.x)
  • PDO_OCI (Oracle Call Interface)
  • PDO_ODBC (ODBC v3 (IBM DB2, unixODBC i win32 ODBC))
  • PDO_PGSQL (PostgreSQL)
  • PDO_SQLITE (SQLite 3 i SQLite 2)
  • PDO_SQLSRV (Microsoft SQL Server)
  • PDO_4D (4D)
Međutim, nisu svi na vašem serveru. Listu dostupnih drajvera možete vidjeti ovako:
print_r(PDO::getAvailableDrivers());

Veza

Metode za povezivanje na različite DBMS-ove mogu se neznatno razlikovati. Ispod su primjeri povezivanja s najpopularnijim. Primijetit ćete da prva tri imaju identičnu sintaksu, za razliku od SQLite-a.
pokušajte ( # MS SQL Server i Sybase preko PDO_DBLIB $DBH = novi PDO("mssql:host=$host;dbname=$dbname", $user, $pass); $DBH = novi PDO("sybase:host=$host ;dbname=$dbname", $user, $pass); # MySQL preko PDO_MYSQL $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); # SQLite $DBH = novi PDO("sqlite:my/database/path/database.db" catch(PDOException $e) ( echo $e->getMessage(); )
Obratite pažnju na blok try/catch - uvijek je vrijedno umotati sve vaše PDO operacije u njega i koristiti mehanizam izuzetaka (više o tome kasnije).

$DBH je skraćenica za “database handle” i koristit će se u cijelom članku.

Možete zatvoriti bilo koju vezu redefiniranjem njene varijable na null.
# zatvara vezu $DBH = null;
Više informacija o karakterističnim opcijama različitih DBMS-ova i metodama povezivanja na njih možete pronaći na php.net.

Izuzeci i PDO

PDO može izbaciti izuzetke na greške, tako da bi sve trebalo biti u bloku try/catch. Odmah nakon kreiranja veze, PDO se može staviti u bilo koji od tri načina greške:
$DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Ali vrijedi napomenuti da će greška prilikom pokušaja povezivanja uvijek izazvati izuzetak.

PDO::ERRMODE_SILENT

Ovo je zadani način rada. Vjerovatno ćete koristiti otprilike istu stvar da uhvatite greške u mysql i mysqli ekstenzijama. Sljedeća dva načina su pogodnija za DRY programiranje.

PDO::ERRMODE_WARNING

Ovaj način će uzrokovati standardno upozorenje i omogućiti skriptu da nastavi izvršavanje. Pogodno za otklanjanje grešaka.

PDO::ERRMODE_EXCEPTION

U većini situacija, ova vrsta kontrole izvršavanja skripte je poželjnija. Izbacuje izuzetak, omogućavajući vam da pametno rukujete greškama i sakrijete osjetljive informacije. Kao, na primjer, ovdje:
# pokušajte povezati se sa bazom podataka ( $DBH = novi PDO("mysql:host=$host;dbname=$dbname", $user, $pass); $DBH->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) # Prokletstvo ukucao sam DELECT umjesto SELECT ("DELECT name FROM people") -> execute() catch(PDOException) (echo "Houston, imamo probleme."); "PDOErrors" .txt", $e->getMessage(), FILE_APPEND); )
Postoji sintaksička greška u SQL izrazu koja će baciti izuzetak. Možemo zabilježiti detalje greške u log fajlu i nagovijestiti korisniku na ljudskom jeziku da se nešto dogodilo.

Umetanje i ažuriranje

Umetanje novih podataka i ažuriranje postojećih podataka neke su od najčešćih operacija baze podataka. U slučaju PDO, ovaj proces se obično sastoji od dva koraka. (Sljedeći odjeljak je sve o UPDATE i INSERT)


Trivijalan primjer umetanja novih podataka:
# STH znači "Statement Handle" $STH = $DBH->prepare("INSERT INTO folks (first_name) values" ("Cathy")"); $STH->izvrši();
Zapravo, možete učiniti istu stvar s jednom exec() metodom, ali metoda u dva koraka daje sve prednosti pripremljenih izjava. Pomažu u zaštiti od SQL injekcija, pa ih ima smisla koristiti čak i za jednokratni upit.

Pripremljene izjave

Korištenje pripremljenih izjava jača zaštitu od SQL injekcija.

Prepared izraz je unaprijed kompajlirani SQL izraz koji se može izvoditi više puta slanjem samo različitih skupova podataka na poslužitelj. Dodatna prednost je to što je nemoguće izvršiti SQL injekciju kroz podatke koji se koriste u rezerviranim mjestima.

U nastavku su tri primjera pripremljenih izjava.
# bez rezerviranih mjesta - vrata za SQL injekcije su otvorena! $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti ($name, $addr, $city)"); # neimenovani čuvari mjesta $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (?, ?, ?)"); # imenovani čuvari mjesta $STH = $DBH->prepare("INSERT INTO folks (name, addr, city) vrijednosti (:name, :addr, :city)");
Prvi primjer je ovdje samo radi poređenja i treba ga izbjegavati. Razlika između bezimenih i imenovanih čuvara mjesta je u tome kako prosljeđujete podatke pripremljenim izjavama.

Neimenovani čuvari mjesta

# dodjeljuje varijable svakom čuvaru mjesta, sa indeksima od 1 do 3 $STH->bindParam(1, $name); $STH->bindParam(2, $addr); $STH->bindParam(3, $city); # umetnite jedan red $name = "Daniel" $addr = "1 Wicked Way"; $city = "Arlington Heights"; $STH->izvrši(); # umetnite drugi red, sa drugačijim podacima $name = "Steve" $addr = "5 Circle Drive"; $city = "Šaumburg"; $STH->izvrši();
Ovdje postoje dva koraka. Na prvom dodjeljujemo varijable svim placeholderima (redovi 2-4). Zatim ovim varijablama dodjeljujemo vrijednosti i izvršavamo upit. Da biste poslali novi skup podataka, jednostavno promijenite vrijednosti varijabli i ponovo pokrenite zahtjev.

Ako vaš SQL izraz ima mnogo parametara, tada je dodjeljivanje varijable svakom vrlo nezgodno. U takvim slučajevima možete pohraniti podatke u niz i proslijediti ih:
# skup podataka koji ćemo umetnuti $data = array("Cathy", "9 Dark and Twisty Road", "Cardiff"); $STH = $DBH->prepare("INSERT INTO ljudi (ime, adresa, grad) vrijednosti (?, ?, ?)"); $STH->izvrši($data);
$data će biti umetnuta umjesto prvog čuvara mjesta, $data umjesto drugog, itd. Ali budite oprezni: ako su vam indeksi pokvareni, ovo neće raditi.

Imenovani čuvari mjesta

# prvi argument je ime čuvara mjesta # obično počinje dvotočkom # iako radi bez njih $STH->bindParam(":name", $name);
Ovdje također možete proslijediti niz, ali on mora biti asocijativan. Ključevi bi trebali biti, kao što možete pretpostaviti, imena čuvara mjesta.
# podaci koje ubacujemo $data = array("name" => "Cathy", "addr" => "9 Dark and Twisty", "city" => "Cardiff"); $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (:name, :addr, :city)"); $STH->izvrši($data);
Jedna od pogodnosti korištenja imenovanih čuvara mjesta je mogućnost umetanja objekata direktno u bazu podataka ako se imena svojstava podudaraju s imenima parametara. Na primjer, možete umetnuti podatke ovako:
# klasa za jednostavnu klasu objekata person ( public $name; public $addr; public $city; function __construct($n,$a,$c) ( $this->name = $n; $this->addr = $ a $this->city = $c ) # tako dalje... ) $cathy = new person("Cathy","9 Dark and Twisty","Cardiff"); # i evo zanimljivog dijela $STH = $DBH->prepare("INSERT INTO folks (ime, addr, city) vrijednosti (:name, :addr, :city)"); $STH->execute((niz)$cathy);
Konvertovanje objekta u niz tokom execute() uzrokuje da se svojstva tretiraju kao ključevi niza.

Uzorkovanje podataka



Podaci se mogu preuzeti pomoću metode ->fetch(). Pre nego što ih pozovete, preporučljivo je da eksplicitno naznačite u kom obliku su vam potrebni. Postoji nekoliko opcija:
  • PDO::FETCH_ASSOC: vraća niz sa imenima kolona kao ključevima
  • PDO::FETCH_BOTH (zadano): vraća niz sa indeksima u obliku naziva kolona i njihovih serijskih brojeva
  • PDO::FETCH_BOUND: dodjeljuje vrijednosti stupaca odgovarajućim varijablama navedenim pomoću metode ->bindColumn().
  • PDO::FETCH_CLASS: dodjeljuje vrijednosti stupaca odgovarajućim svojstvima navedene klase. Ako ne postoji svojstvo za neki stupac, biće kreirano
  • PDO::FETCH_INTO: ažurira postojeću instancu navedene klase
  • PDO::FETCH_LAZY: kombinuje PDO::FETCH_BOTH i PDO::FETCH_OBJ
  • PDO::FETCH_NUM: vraća niz sa ključevima kao brojevima kolona
  • PDO::FETCH_OBJ: vraća anonimni objekat sa svojstvima koja odgovaraju imenima kolona
U praksi će vam obično trebati tri: FETCH_ASSOC, FETCH_CLASS i FETCH_OBJ. Da biste naveli format podataka, koristite sljedeću sintaksu:
$STH->setFetchMode(PDO::FETCH_ASSOC);
Možete ga postaviti i direktno kada pozivate metodu ->fetch().

FETCH_ASSOC

Ovaj format kreira asocijativni niz s imenima stupaca kao indeksima. To bi trebalo biti poznato onima koji koriste mysql/mysqli ekstenzije.
# budući da je ovo običan upit bez čuvara mjesta, # možete odmah koristiti query() metodu $STH = $DBH->query("SELECT name, addr, city from folks"); # postavlja način preuzimanja $STH->setFetchMode(PDO::FETCH_ASSOC); while($row = $STH->fetch()) ( echo $row["name"] . "\n"; echo $row["addr"] . "\n"; echo $row["city"] "\n" ;
Petlja while() će iterirati kroz cijeli rezultat upita.

FETCH_OBJ

Ova vrsta akvizicije podataka kreira instancu std klase za svaki red.
# kreiraj upit $STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); # biramo način preuzimanja $STH->setFetchMode(PDO::FETCH_OBJ); # ispisuje rezultat while($row = $STH->fetch()) ( echo $row->name . "\n"; echo $row->addr . "\n"; echo $row->city . " \ n"; )

FETCH_CLASS

Kada se koristi fetch_class, podaci se zapisuju u instance navedene klase. U ovom slučaju, vrijednosti se dodjeljuju svojstvima objekta PRIJE pozivanja konstruktora. Ako svojstva s nazivima koji odgovaraju imenima stupaca ne postoje, bit će kreirana automatski (sa javnim opsegom).

Ako vaši podaci zahtijevaju obaveznu obradu odmah nakon što su primljeni iz baze podataka, mogu se implementirati u konstruktoru klase.

Na primjer, uzmimo situaciju u kojoj trebate sakriti dio adrese stanovanja osobe.
class secret_person ( public $name; javni $addr; javni $city; javni $other_data; funkcija __construct($other = "") ( $this->addr = preg_replace("//", "x", $this-> addr $this->other_data = $other);
Prilikom kreiranja objekta, sva mala latinična slova moraju biti zamijenjena sa x. hajde da proverimo:
$STH = $DBH->query("IZABERI ime, adresu, grad od ljudi"); $STH->setFetchMode(PDO::FETCH_CLASS, "secret_person"); while($obj = $STH->fetch()) ( echo $obj->addr; )
Ako adresa u bazi podataka izgleda kao '5 Rosebud', onda će izlaz biti '5 Rxxxxxx'.

Naravno, ponekad ćete htjeti da se konstruktor pozove PRIJE dodjeljivanja vrijednosti. PDO dozvoljava i ovo.
$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, "tajna_osoba");
Sada kada ste prethodni primjer dopunili dodatnom opcijom (PDO::FETCH_PROPS_LATE), adresa se neće mijenjati, jer se ništa ne dešava nakon što se vrijednosti upišu.

Konačno, ako je potrebno, možete proslijediti argumente konstruktoru direktno prilikom kreiranja objekta:
$STH->setFetchMode(PDO::FETCH_CLASS, "secret_person", array("stuff"));
Možete čak proslijediti različite argumente svakom objektu:
$i = 0; while($rowObj = $STH->fetch(PDO::FETCH_CLASS, "secret_person", array($i))) ( // uradi nešto $i++; )

Druge korisne metode

Iako ovaj članak ne može (i ne pokušava da pokrije) svaki aspekt rada sa PDO-om (to je ogroman modul!), sljedećih nekoliko karakteristika ne može biti izostavljeno bez spominjanja.
$DBH->lastInsertId();
Metoda ->lastInsertId() vraća id posljednjeg umetnutog zapisa. Vrijedi napomenuti da se uvijek poziva na objektu baze podataka (koji se u ovom članku naziva $DBH), a ne na objektu s izrazom ($STH).
$DBH->exec("IZBRIŠI IZ ljudi GDJE 1"); $DBH->exec("SET time_zone = "-8:00"");
Metoda ->exec() se koristi za operacije koje ne vraćaju nikakve podatke osim broja zapisa na koje utiču.
$safe = $DBH->quote($nesigurno);
Metoda ->quote() postavlja navodnike u nizove podataka tako da ih je sigurno koristiti u upitima. Korisno ako ne koristite pripremljene izjave.
$rows_affected = $STH->rowCount();
Metoda ->rowCount() vraća broj zapisa koji su učestvovali u operaciji. Nažalost, ova funkcija nije radila sa SELECT upitima do PHP 5.1.6. Ako nije moguće ažurirati PHP verziju, broj zapisa se može dobiti na sljedeći način:
$sql = "IZABIR BROJ(*) OD ljudi"; if ($STH = $DBH->query($sql)) ( # provjeri broj zapisa if ($STH->fetchColumn() > 0) ( # izvrši potpunu selekciju ovdje jer su podaci pronađeni! ) else ( # ispisati poruku da nisu pronađeni podaci koji zadovoljavaju zahtjev) )

Zaključak

Nadam se da će ovaj materijal pomoći nekima od vas da pređu sa mysql i mysqli ekstenzija.

Postavljanje i korištenje PDO - PHP Data Objects ekstenzije za rad sa bazama podataka

Kreiranje testne baze podataka i tabele

Prvo, napravimo bazu podataka za ovaj vodič:

CREATE DATABASE solarni_sistem; DODAJTE SVE PRIVILEGIJE NA solarnom_sistemu.* "testuser"@"localhost" IDENTIFIKOVANOM POMOĆU "testpassword";

Korisniku sa login testuser i lozinkom testpassword je odobreno puno pravo pristupa bazi podataka solar_system.

Sada napravimo tabelu i popunimo je podacima čija se astronomska tačnost ne podrazumeva:

USE solar_system; CREATE TABLE planete (id TINYINT(1) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARNI KLJUČ(id), ime VARCHAR(10) NOT NULL, boja VARCHAR(10) NOT NULL); INSERT INTO planets(ime, boja) VALUES("zemlja", "plava"), ("mars", "crvena"), ("jupiter", "čudno");

Opis veze

Sada kada je baza podataka kreirana, definišimo DSN () - informacije za povezivanje sa bazom podataka, predstavljene kao niz. Sintaksa opisa se razlikuje ovisno o korištenom DBMS-u. U primjeru radimo sa MySQL/MariaDB, pa navodimo:

  • ime hosta na kojem se nalazi DBMS;
  • port (opciono ako se koristi standardni port 3306);
  • naziv baze podataka;
  • kodiranje (opciono).

DSN linija u ovom slučaju izgleda ovako:

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

Prvo se specificira prefiks baze podataka. U primjeru - mysql. Prefiks je odvojen od ostatka retka dvotočkom, a svaki sljedeći parametar je odvojen točkom i zarezom.

Kreiranje PDO objekta

Sada kada je DSN niz spreman, kreirajmo PDO objekat. Konstruktor ulaza prihvata sledeće parametre:

  1. DSN string.
  2. Ime korisnika koji ima pristup bazi podataka.
  3. Lozinka ovog korisnika.
  4. Niz sa dodatnim parametrima (opciono).
$options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]; $pdo = novi PDO($dsn, "testuser", "testpassword", $options);

Dodatni parametri se također mogu definirati nakon što je objekt kreiran pomoću metode SetAttribute:

$pdo->SetAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

Definiranje standardne metode uzorkovanja

PDO::DEFAULT_FETCH_MODE je važan parametar koji određuje zadanu metodu preuzimanja. Navedena metoda se koristi kada se dobije rezultat zahtjeva.

PDO::FETCH_BOTH

Zadani način rada. Rezultat odabira je indeksiran i brojevima (počevši od 0) i nazivima stupaca:

$stmt = $pdo->query("SELECT * FROM planets"); $results = $stmt->fetch(PDO::FETCH_BOTH);

Nakon izvršenja upita sa ovim načinom prema test tablici planeta, dobivamo sljedeći rezultat:

Niz ( => 1 => 1 => zemlja => zemlja => plava => plava)

PDO::FETCH_ASSOC

Rezultat je pohranjen u asocijativnom nizu u kojem je ključ naziv stupca, a vrijednost je odgovarajuća vrijednost reda:

$stmt = $pdo->query("SELECT * FROM planets"); $results = $stmt->fetch(PDO::FETCH_ASSOC);

Kao rezultat dobijamo:

Niz ( => 1 => zemlja => plava)

PDO::FETCH_NUM

Kada koristite ovaj način rada, rezultat se prikazuje kao niz indeksiran brojevima stupaca (počevši od 0):

Niz ( => 1 => zemlja => plava)

PDO::FETCH_COLUMN

Ova opcija je korisna ako trebate dobiti listu vrijednosti za jedno polje u obliku jednodimenzionalnog niza, čija numeracija počinje od 0. Na primjer:

$stmt = $pdo->query("IZABERI ime SA planeta");

Kao rezultat dobijamo:

Niz ( => zemlja => mars => jupiter)

PDO::FETCH_KEY_PAIR

Ovu opciju koristimo ako trebamo dobiti listu vrijednosti dva polja u obliku asocijativnog niza. Ključevi niza su podaci u prvoj koloni selekcije, vrijednosti niza su podaci u drugoj koloni. na primjer:

$stmt = $pdo->query("IZABIR ime, boja SA planeta"); $result = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);

Kao rezultat dobijamo:

Niz ( => plavo => crveno => čudno)

PDO::FETCH_OBJECT

Kada koristite PDO::FETCH_OBJECT, anonimni objekat se kreira za svaki dohvaćeni red. Njegova javna svojstva su imena oglednih kolona, ​​a rezultati upita se koriste kao njihove vrijednosti:

$stmt = $pdo->query("IZABIR ime, boja SA planeta"); $results = $stmt->fetch(PDO::FETCH_OBJ);

Kao rezultat dobijamo:

StdClass objekat ( => zemlja => plava)

PDO::FETCH_CLASS

U ovom slučaju, kao iu prethodnom, vrijednosti stupaca postaju svojstva objekta. Međutim, morate navesti postojeću klasu koja će se koristiti za kreiranje objekta. Pogledajmo ovo na primjeru. Prvo, napravimo klasu:

Class Planet (privatna $name; privatna $color; javna funkcija setName($planet_name) ( $this->name = $planet_name; ) javna funkcija setColor($planet_color) ( $this->color = $planet_color; ) javna funkcija getName () ( vrati $this->name; ) javna funkcija getColor() ( vrati $this->color; ) )

Imajte na umu da klasa Planet ima privatna svojstva i da nema konstruktora. Sada izvršimo zahtjev.

Ako koristite metodu dohvaćanja sa PDO::FETCH_CLASS, morate koristiti metodu setFetchMode prije slanja zahtjeva za dohvaćanje podataka:

$stmt = $pdo->query("IZABIR ime, boja SA planeta"); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet");

Prvi parametar koji prosljeđujemo metodi setFetchMode je konstanta PDO::FETCH_CLASS. Drugi parametar je ime klase koja će se koristiti prilikom kreiranja objekta. Sada uradimo:

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

Kao rezultat, dobijamo objekat Planeta:

Planeta Objekat ( => zemlja => plava)

Vrijednosti koje vraća upit se dodjeljuju odgovarajućim svojstvima objekta, čak i privatnim.

Definiranje svojstava nakon izvršenja konstruktora

Klasa Planet nema eksplicitni konstruktor, tako da neće biti problema sa dodjeljivanjem svojstava. Ako klasa ima konstruktor u kojem je svojstvo dodijeljeno ili promijenjeno, oni će biti prepisani.

Kada koristite konstantu FETCH_PROPS_LATE, vrijednosti svojstva će biti dodijeljene nakon što se konstruktor izvrši:

Class Planet ( privatno $name; privatna $color; javna funkcija __construct($name = mjesec, $color = siva) ( $this->name = $name; $this->color = $color; ) javna funkcija setName($ planet_name) ( $this->name = $planet_name; ) javna funkcija setColor($planet_color) ( $this->color = $planet_color; ) javna funkcija getName() (vrati $this->name; ) javna funkcija getColor() (vrati $this->color; ) )

Modificirali smo klasu Planet dodavanjem konstruktora koji uzima dva argumenta kao ulaz: ime i boju. Podrazumevane vrednosti za ova polja su mesec i siva, respektivno.

Ako ne koristite FETCH_PROPS_LATE, svojstva će biti prepisana sa zadanim vrijednostima kada se objekt kreira. Hajde da to proverimo. Prvo pokrenimo upit:

$stmt = $pdo->query("IZABERI ime, boju IZ solarnog_sistema WHERE ime = "zemlja""); $stmt->setFetchMode(PDO::FETCH_CLASS, "Planet"); $planet = $stmt->fetch(); var_dump($planet);

Kao rezultat dobijamo:

Object(Planet)#2 (2) ( ["name":"Planet":private]=> string(4) "moon" ["color":"Planet":private]=> string(4) "grey" )

Kao što se i očekivalo, vrijednosti preuzete iz baze podataka se prepisuju. Sada pogledajmo rješavanje problema pomoću FETCH_PROPS_LATE (sličan zahtjev):

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet"); $planet = $stmt->fetch(); var_dump($planet);

Kao rezultat, dobijamo ono što nam je potrebno:

Object(Planet)#4 (2) ( ["name":"Planet":private]=> string(5) "earth" ["color":"Planet":private]=> string(4) "blue" )

Ako konstruktor klase nema zadane vrijednosti, ali su potrebne, parametri konstruktora se postavljaju prilikom pozivanja metode setFetchMode sa trećim argumentom u obliku niza. na primjer:

Class Planet ( privatno $name; privatno $color; javna funkcija __construct($name, $color) ( $this->name = $name; $this->color = $color; ) [...])

Argumenti konstruktora su potrebni, pa hajde da uradimo:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, "Planet", ["mjesec", "siva"]);

Dolazni parametri također djeluju kao zadane vrijednosti koje su potrebne za inicijalizaciju. U budućnosti će oni biti prepisani vrijednostima iz baze podataka.

Dohvaćanje višestrukih objekata

Više rezultata se dohvaćaju kao objekti koristeći metodu dohvaćanja unutar while petlje:

Dok ($planet = $stmt->fetch()) ( // rezultati obrade)

Ili uzorkovanjem svih rezultata odjednom. U drugom slučaju koristi se metoda fetchAll, a način se specificira u trenutku poziva:

$stmt->fetchAll(PDO::FETCH_CLASS|PDO_FETCH_PROPS_LATE, "Planet", ["mjesec", "siva"]);

PDO::FETCH_INTO

Kada je odabrana ova opcija odabira, PDO ne kreira novi objekt, već ažurira svojstva postojećeg. Međutim, ovo je moguće samo za javna svojstva ili kada koristite magičnu metodu __set na objektu.

Pripremljeni i direktni zahtjevi

Postoje dva načina za izvršavanje upita u PDO-u:

  • ravno, koji se sastoji od jednog koraka;
  • pripremljena, koja se sastoji od dva koraka.

Direktni zahtjevi

Postoje dvije metode za izvođenje direktnih upita:

  • query se koristi za izraze koji ne unose promjene, kao što je SELECT. Vraća PDOStatemnt objekat iz kojeg se dohvaćaju rezultati upita pomoću metoda dohvati ili fetchAll;
  • exec se koristi za naredbe kao što su INSERT, DELETE ili UPDATE. Vraća broj redova obrađenih zahtjevom.

Direktni operatori se koriste samo ako u upitu nema varijabli i ako ste sigurni da je upit siguran i da je ispravno izbačen.

Pripremljeni upiti

PDO podržava pripremljene naredbe, koje su korisne za zaštitu aplikacije od: metoda pripreme izvodi potrebno izbjegavanje.

Pogledajmo primjer. Želite da umetnete svojstva objekta Planet u tabelu Planeta. Prvo, pripremimo zahtjev:

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(?, ?)");

Koristimo metod pripreme, koji uzima SQL upit sa pseudo-varijablama (placeholders) kao argument. Pseudovarijable mogu biti dvije vrste: neimenovane i imenovane.

Neimenovane pseudo varijable

Neimenovane pseudovarijable (pozicione placeholders) su označene sa ? . Rezultirajući upit je kompaktan, ali zahtijeva da se vrijednosti zamijene istim redoslijedom. Oni se prosljeđuju kao niz putem execute metode:

$stmt->execute([$planet->name, $planet->color]);

Imenovane pseudo varijable

Kada koristite imenovane čuvare mjesta, redoslijed kojim se vrijednosti prosljeđuju za zamjenu nije važan, ali kod u ovom slučaju postaje manje kompaktan. Podaci se prosljeđuju metodi execute u obliku asocijativnog niza, u kojem svaki ključ odgovara imenu pseudo-varijable, a vrijednost niza odgovara vrijednosti koju treba zamijeniti u zahtjevu. Ponovimo prethodni primjer:

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(:name, :color)"); $stmt->execute(["name" => $planet->name, "color" => $planet->color]);

Metode pripreme i izvršenja koriste se i prilikom izvršavanja zahtjeva za promjenom i prilikom dohvaćanja.

A informacije o broju obrađenih redova, ako je potrebno, pružit će se metodom rowCount.

Kontroliranje ponašanja PDO greške

Parametar odabira načina greške PDO::ATTR_ERRMODE se koristi za određivanje kako se PDO ponaša u slučaju greške. Dostupne su tri opcije: PDO::ERRMODE_SILENT, PDO::ERRMODE_EXCEPTION i PDO::ERRMODE_WARNING.

PDO::ERRMODE_SILENT

Zadana opcija. PDO će jednostavno snimiti informacije o grešci, do kojih će vam pomoći metode errorCode i errorInfo.

PDO::ERRMODE_EXCEPTION

Ovo je poželjna opcija gdje PDO izbacuje izuzetak (PDOException) pored informacija o grešci. Izuzetak prekida izvršavanje skripte, što je korisno kada se koriste PDO transakcije. Primjer je dat u opisu transakcija.

PDO::ERRMODE_WARNING

U ovom slučaju, PDO također bilježi informacije o grešci. Tok skripte se ne prekida, ali se izdaju upozorenja.

metode bindValue i bindParam

Također možete koristiti metode bindValue i bindParam za zamjenu vrijednosti u upitu. Prvi povezuje vrijednost varijable s pseudo-varijablom koja se koristi za pripremu zahtjeva:

$stmt = $pdo->prepare("INSERT INTO planets(name, color) VALUES(:name, :color)"); $stmt->bindValue("name", $planet->name, PDO::PARAM_STR);

Povezao je vrijednost varijable $planet->name sa pseudo varijablom:name. Imajte na umu da kada koristite metode bindValue i bindParam, tip varijable je specificiran kao treći argument koristeći odgovarajuće PDO konstante. U primjeru - PDO::PARAM_STR .

Metoda bindParam vezuje varijablu za pseudo varijablu. U ovom slučaju, varijabla je povezana s referencom pseudo-varijable, a vrijednost će biti umetnuta u upit tek nakon što se pozove metoda izvršenja. Pogledajmo primjer:

$stmt->bindParam("name", $planet->name, PDO::PARAM_STR);

Transakcije u PDO

Zamislimo neobičan primjer. Korisnik treba da odabere listu planeta i svaki put kada se zahtev izvrši, trenutni podaci se brišu iz baze podataka, a zatim se ubacuju novi. Ako dođe do greške nakon brisanja, sljedeći korisnik će dobiti praznu listu. Da bismo to izbjegli, koristimo transakcije:

$pdo->beginTransaction(); try ( $stmt1 = $pdo->exec("IZBRIŠI SA planeta"); $stmt2 = $pdo->prepare("INSERT INTO planets(name, color) VALUES (?, ?)"); foreach ($planets as as). $planet) ( $stmt2->execute([$planet->getName(), $planet->getColor()]); ) $pdo->commit() ) catch (PDOException $e) ( $pdo-> rollBack ();

Metoda beginTransaction onemogućava automatsko izvršavanje zahtjeva, a unutar konstrukcije try-catch, zahtjevi se izvršavaju željenim redoslijedom. Ako se ne izbace PDOExceptions, zahtjevi će biti dovršeni korištenjem metode urezivanja. U suprotnom, oni će biti vraćeni metodom vraćanja unazad, a automatsko izvršavanje upita će biti vraćeno.

Ovo je stvorilo konzistentnost u izvršavanju upita. Očigledno, da bi se ovo dogodilo, PDO::ATTR_ERRMODE treba biti postavljen na PDO::ERRMODE_EXCEPTION.

Zaključak

Sada kada je rad sa PDO opisan, napomenimo njegove glavne prednosti:

  • sa PDO je lako prenijeti aplikaciju na druge DBMS;
  • Podržani su svi popularni DBMS-ovi;
  • ugrađeni sistem za upravljanje greškama;
  • razne opcije za predstavljanje rezultata uzorka;
  • Podržani su pripremljeni upiti koji skraćuju kod i čine ga otpornim na SQL injekcije;
  • Podržane su transakcije koje pomažu u održavanju integriteta podataka i konzistentnosti upita kada korisnici rade paralelno.
Operacija