Pyetjet e përgatitura dhe procedurat e ruajtura. Si të punoni me PDO? Udhëzues i plotë Pyetjet e përgatitura pdo

Në këtë artikull të fundit do të shikojmë, cilat janë pyetjet e përgatitura, si të kapni gabimet Dhe çfarë janë transaksionet në PDO.

Pyetje të përgatitura

Kur kryejmë një pyetje në një bazë të dhënash, ajo analizohet dhe optimizohet, gjë që natyrisht kërkon kohë. Nëse kemi shumë pyetje komplekse, atëherë kjo mund të marrë një kohë shumë të gjatë për t'u përfunduar. Duke përdorur të njëjtën pyetje të përgatitura, kjo bëhet një herë dhe më pas mund ta përdorim pyetjen tonë sa herë të duam. Gjithashtu, nuk kemi nevojë t'u shpëtojmë parametrave, sepse drejtuesi i bazës së të dhënave do të bëjë gjithçka vetë. Le të shohim se si t'i përdorim ato.

$stmt = $db->prepare("INSERT INTO artikujt (titulli, teksti) VLERAT (:title, :tekst)");
$stmt->bindParam(":title", $title);
$stmt->bindParam(":text", $text);



$stmt->ekzekutoni();



$stmt->ekzekutoni();

Për të përgatitur kërkesën, ne e shkruajmë atë në metodë përgatisin, ku në vend të vlerave tregojmë një rresht si kjo: ": Emri". Në metodë bindParam ne tregojmë se cilës rresht çfarë të dhënash t'i bashkëngjitni. Në rastin tonë, në linjë :titulli të dhënat nga një variabël janë të lidhura $titull, dhe në linjë :tekst- të dhëna nga ndryshorja $tekst. Për të ekzekutuar kërkesën, duhet të telefononi metodën ekzekutuar. Parametra të tillë quhen emërtuar, tani le të shohim pa emër.

$stmt = $db->prepare("INSERT INTO artikujt (titulli, teksti) VLERAT (?, ?)");
$stmt->bindParam(1, $title);
$stmt->bindParam(2, $text);

$title = "titulli i nenit 1";!}
$text = "Disa tekst për artikullin e parë";
$stmt->ekzekutoni();

$title = "titulli i nenit 2";!}
$text = "Disa tekst për artikullin e dytë";
$stmt->ekzekutoni();

Gjithçka këtu është identike, përveç se në vend të vijës : Emri tregohet një pikëpyetje dhe në metodë bindParam numri 1 do të thotë së pari një pikëpyetje dhe një numër 2 - e dyta pikëpyetje. Përdorni metodën që ju pëlqen më shumë.

Gabimet e kapjes

Për të kapur gabimet, ne përdorim një ndërtim që është tashmë i njohur për ne provo-kap dhe klasës Përjashtim PDO.

provoni (
$db = PDO e re ("myql:host=$host;dbname=$dbname", $user, $pass);
) catch(PDOException $e) (
echo "Ju keni një gabim: ".$e->getMessage()."
";
echo "On line: ".$e->getLine();
}

Si shembull, bëra një gabim dhe shkrova myql, jo mysql. Ky gabim do të kapet dhe do të na shfaqet teksti i tij dhe në cilën rresht ka ndodhur gabimi.

Transaksionet

Le t'i hedhim një sy transaksionet menjëherë me një shembull.

provoni (
$db = PDO e re ("mysql:host=$host;dbname=$dbname", $user, $pass);
$db->fillimi i Transaksionit();

$stmt = $db->exec("INSERT INTO `articles`(`title`) VALUES("title1")");
$stmt = $db->exec("INSERT INTO `artikuj`(`titulli`) VALUES("title2")");
dalje ("gabim");

$stmt = $db->exec("INSERT INTO `articles`(`title`) VLERAT ("title3")");
$db->commit();

) catch(PDOException $e) (
$db->Rrotullimi();
}

fillimi i transaksionit do të thotë se ne po fillojmë një transaksion. Angazhohen konfirmon ndryshimet dhe kthim mbrapa anulon gjithçka.

Thelbi i transaksioneve është se ne ose bëjmë gjithçka ose nuk bëjmë asgjë. Në shembullin tonë, ne fusim në tabelë artikuj vlerat titulli1, titulli2, titulli 3. Por pas futjes së vlerës së dytë, ne simuluam një gabim duke ndaluar përdorimin e skriptit dalje. Nëse nuk do të përdornim transaksionet, atëherë kemi dy të parat titullin do të ishte futur, por i fundit jo. Në shembullin tonë, kjo nuk është domethënëse, por ka raste kur kjo mund të çojë në dështime serioze në aplikacion. Pra, për të parandaluar që kjo të ndodhë, ne përdorim transaksionet, ku metoda kthim mbrapa do të kthejë gjithçka në formën e saj origjinale dhe dy të parat tona titullin gjithashtu nuk do të futet, dhe nëse gjithçka shkoi mirë, pa gabime, atëherë metoda angazhohen do të konfirmojë ndryshimet dhe të treja titullin do të futet me sukses.

konkluzioni

Pra, në tre artikujt tanë kushtuar mësimi i PDO, ne kemi mbuluar gjithçka që ju nevojitet për të përdorur me lehtësi këtë ndërfaqe. Unë mendoj se ju e kuptoni se si PDO na e bën jetën më të lehtë dhe ju do ta përdorni në projektet tuaja. fat të mirë!












PDO ka metodën e vet të zgjuar të lidhjes të quajtur . Plus, gjatë lidhjes mund të vendosni një mori opsionesh, disa prej të cilave janë jashtëzakonisht të dobishme. Mund të gjendet një listë e plotë, por vetëm disa janë të rëndësishme.

Shembull i një lidhjeje të saktë:

$host = "127.0.0.1" ;
$db = "test" ;
$user = "rrënjë" ;
$pass = "" ;
$charset = "utf8" ;

$dsn = "mysql:host= $host ;dbname= $db ;charset= $charset " ;
$opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => e rreme,
];
$pdo = PDO e re ($dsn, $user, $pass, $opt);

Çfarë po ndodh këtu?

$dsn specifikon llojin e bazës së të dhënave me të cilën do të punojmë (mysql), hostin, emrin e bazës së të dhënave dhe grupin e karaktereve.
- e ndjekur nga emri i përdoruesit dhe fjalëkalimi
- pas së cilës specifikohet një grup opsionesh, për të cilat nuk shkruhet në asnjë nga manualet.

Pavarësisht nga fakti se ky grup është një gjë jashtëzakonisht e dobishme, siç u përmend më lart. Gjëja më e rëndësishme është që mënyra e gabimit duhet të vendoset vetëm në formën e përjashtimeve.
- Së pari, sepse në të gjitha mënyrat e tjera PDO nuk raporton asgjë të kuptueshme për gabimin,
- së dyti, sepse përjashtimi gjithmonë përmban një gjurmë të pazëvendësueshme të pirgut,
- së treti, përjashtimet janë jashtëzakonisht të përshtatshme për t'u trajtuar.

Plus, është shumë i përshtatshëm për të vendosur FETCH_MODE si parazgjedhje, në mënyrë që të mos shkruhet në ÇDO kërkesë, siç duan të bëjnë hamsterët e zellshëm.
Gjithashtu këtu mund të vendosni modalitetin e lidhjes, emulimin e shprehjeve të përgatitura dhe shumë fjalë të tjera të frikshme.

Si rezultat, marrim variablin $pdo, me të cilin punojmë gjatë gjithë skriptit.

Ju mund të përdorni dy metoda për të ekzekutuar pyetje.
Nëse asnjë variabla nuk i kalohet kërkesës, atëherë mund të përdorni funksionin query(). Ai do të ekzekutojë kërkesën dhe do të kthejë një objekt të veçantë - deklaratën PDO. Shumë përafërsisht, mund ta krahasoni atë me burimin mysql, i cili u kthye nga mysql_query(). Ju mund të merrni të dhëna nga ky objekt ose në mënyrë tradicionale, përmes while, ose përmes foreach(). Ju gjithashtu mund të kërkoni kthimin e të dhënave të marra në një format të veçantë, i cili diskutohet më poshtë.
$stmt = $pdo -> pyetje ("ZGJEDH emrin NGA përdoruesit" );
ndërsa ($row = $stmt -> fetch())
{
}

Nëse të paktën një variabël i kalohet kërkesës, atëherë kjo kërkesë është të detyrueshme duhet të bëhet vetëm përmes shprehjet e përgatitura. Çfarë është ajo? Ky është një pyetje e rregullt SQL, në të cilën vendoset një shënues i veçantë në vend të një ndryshoreje - një mbajtës vendi. PDO mbështet vendmbajtësit pozicional (?), për të cilët renditja e variablave të kaluar është e rëndësishme, dhe mbajtësit e emërtuar (:name), për të cilët rendi nuk është i rëndësishëm. Shembuj:
$sql = ;
$sql = ;

Për të ekzekutuar një pyetje të tillë, fillimisht duhet të përgatitet duke përdorur funksionin përgatit (). Ai gjithashtu kthen një deklaratë PDO, por pa asnjë të dhënë ende. Për t'i marrë ato, duhet ta ekzekutoni këtë kërkesë, duke kaluar më parë variabla në të. Mund ta transferoni në dy mënyra:
Më shpesh, thjesht mund të ekzekutoni metodën execute(), duke i kaluar asaj një grup variablash:
$stmt = $pdo -> përgatit ( "ZGJIDH emrin NGA përdoruesit WHERE email = ?");
$stmt -> ekzekutoni (array($email ));

$stmt = $pdo -> përgatit ( "ZGJIDH emrin NGA përdoruesit WHERE email = :email");
$stmt -> ekzekutoni (array("email" => $email ));
Siç mund ta shihni, në rastin e mbajtësve të vendeve me emër, një grup në të cilin çelësat duhet të përputhen me emrat e mbajtësve të vendeve duhet të kalohet për të ekzekutuar().

Ndonjëherë, shumë rrallë, metoda e dytë mund të kërkohet, kur variablat fillimisht lidhen me kërkesën një nga një, duke përdorur bindValue() / bindParam(), dhe pastaj ekzekutohen vetëm. Në këtë rast, asgjë nuk kalohet për të ekzekutuar(). Një shembull mund të gjendet në manual.
Kur përdorni këtë metodë, a duhet të preferohet gjithmonë bindValue()? sepse sjellja e bindParam() nuk është e dukshme për fillestarët dhe do të çojë në probleme.

Më pas mund të përdorni deklaratën PDO në të njëjtat mënyra si më sipër. Për shembull, nëpërmjet foreach:
$stmt = $pdo -> përgatit ( "ZGJIDH emrin NGA përdoruesit WHERE email = ?");
$stmt ->
foreach ($stmt si $row )
{
echo $row ["emri"] . "\n" ;
}

E RËNDËSISHME: Shprehjet e përgatitura janë arsyeja kryesore për të përdorur PDO sepse ajo i vetmi mënyrë të sigurt ekzekutimi i pyetjeve SQL që përfshijnë variabla.

Gjithashtu, përgatit() / execute() mund të përdoret për të ekzekutuar në mënyrë të përsëritur një pyetje të përgatitur një herë me grupe të ndryshme të dhënash. Në praktikë, kjo nevojitet jashtëzakonisht rrallë dhe nuk sjell shumë rritje të shpejtësisë. Por në rast se ju duhet të bëni shumë pyetje të të njëjtit lloj, mund ta shkruani kështu:

$data = grup(
1 => 1000,
5 => 300,
9 => 200,
);

$stmt = $pdo -> përgatit ( "Përditësoni përdoruesit SET bonus = bonus + ? KU ID = ?");
foreach ($data si $id => $bonus)
{
$stmt -> ekzekutoni ([ $bonus, $id ]);
}

Këtu e përgatisim kërkesën një herë dhe më pas e ekzekutojmë shumë herë.

Tashmë jemi njohur me metodën fetch(), e cila përdoret për të marrë në mënyrë sekuenciale rreshta nga baza e të dhënave. Kjo metodë është një analog i funksionit mysq_fetch_array() dhe atyre të ngjashëm, por vepron ndryshe: në vend të shumë funksioneve, përdoret këtu një, por sjellja e tij specifikohet nga parametri i kaluar. Do të shkruaj më vonë për këto parametra në detaje, por si rekomandim i shkurtër do të rekomandoja përdorimin e fetch() në modalitetin FETCH_LAZY:
$stmt = $pdo -> përgatit ( "ZGJIDH emrin NGA përdoruesit WHERE email = ?");
$stmt -> ekzekutoni ([ $_GET [ "email" ]]);
ndërsa ($rresht = $stmt -> marr (PDO :: FETCH_LAZY ))
{
jehonë $rresht [0] . "\n" ;
echo $row ["emri"] . "\n" ;
echo $row -> emri . "\n" ;
}

Në këtë mënyrë, asnjë memorie shtesë nuk harxhohet, dhe përveç kësaj, kolonat mund të aksesohen në cilëndo nga tre mënyrat - përmes indeksit, emrit ose pronës.

Deklarata PDO gjithashtu ka një funksion ndihmës për marrjen e vlerës së një kolone të vetme. Është shumë i përshtatshëm nëse kërkojmë vetëm një fushë - në këtë rast sasia e shkrimit zvogëlohet ndjeshëm:
$stmt = $pdo -> përgatit ( "ZGJEDH emrin NGA tabela WHERE id=?");
$stmt -> ekzekutoni (array($id ));
$emri = $stmt -> fetchColumn();

Por funksioni më interesant, me funksionalitetin më të madh, është fetchAll(). Është kjo që e bën PDO një bibliotekë të nivelit të lartë për të punuar me një bazë të dhënash, dhe jo vetëm një drejtues të nivelit të ulët.

FetchAll() kthen një grup që përbëhet nga të gjitha rreshtat që pyeti ktheu. Nga të cilat mund të nxirren dy përfundime:
1. Ky funksion nuk duhet të përdoret kur pyetja kthen shumë të dhëna. Në këtë rast, është më mirë të përdorni një lak tradicional me fetch()
2. Meqenëse në aplikacionet moderne PHP të dhënat nuk nxirren kurrë menjëherë pas marrjes, por transferohen në një shabllon për këtë qëllim, fetchAll() bëhet thjesht i pazëvendësueshëm, duke ju lejuar të shmangni shkrimin e sytheve me dorë, dhe në këtë mënyrë të reduktoni sasinë e kodit.

Marrja e një grupi të thjeshtë.
I thirrur pa parametra, ky funksion kthen një grup të rregullt të indeksuar që përmban rreshta nga baza e të dhënave, në formatin e specifikuar në FETCH_MODE si parazgjedhje. Konstantat PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_OBJ mund të ndryshojnë formatin menjëherë.

Marrja e një kolone.
Ndonjëherë ju duhet të merrni një grup të thjeshtë njëdimensional duke kërkuar një fushë të vetme nga një grup vargjesh. Për ta bërë këtë, përdorni modalitetin PDO::FETCH_COLUMN
$data = $pdo -> pyetësor ("SELECT name FROM users" ) -> fetchAll (PDO :: FETCH_COLUMN );
grup (
0 => "Gjoni" ,
1 => "Mike" ,
2 => "Maria" ,
3 => "Kathy" ,
)

Marrja e çifteve çelës-vlerë.
Gjithashtu një format popullor kur është e dëshirueshme të merret e njëjta kolonë, por e indeksuar jo me numra, por nga një nga fushat. Konstanta PDO::FETCH_KEY_PAIR është përgjegjëse për këtë.
$data = $pdo -> pyetje ("SELECT id, emri FROM users" ) -> fetchAll (PDO :: FETCH_KEY_PAIR );
grup (
104 => "Gjoni" ,
110 => "Mike" ,
120 => "Maria" ,
121 => "Kathy" ,
)

Merrni të gjitha rreshtat të indeksuara nga një fushë.
Gjithashtu shpesh është e nevojshme të merren të gjitha rreshtat nga baza e të dhënave, por gjithashtu të indeksohen jo me numra, por nga një fushë unike. Konstanta PDO::FETCH_UNIQUE e bën këtë.
$data = $pdo -> pyetje ("SELECT * FROM përdoruesit") -> fetchAll (PDO :: FETCH_UNIQUE );
grup (
104 => grup (
"name" => "Gjoni" ,
"car" => "Toyota" ,
),
110 => grup (
"name" => "Mike" ,
"car" => "Ford" ,
),
120 => grup (
"name" => "Maria" ,
"car" => "Mazda" ,
),
121 => grup (
"name" => "Kathy" ,
"car" => "Mazda" ,
),
)

Duhet mbajtur mend se së pari duhet të zgjidhni një fushë unike në kolonë.

Gjithsej mënyra të ndryshme marrja e të dhënave në PDO është më shumë se një duzinë e gjysmë. Plus ju mund t'i kombinoni ato! Por kjo është një temë për një artikull të veçantë.

Kur punoni me shprehje të përgatitura, duhet të kuptoni se një mbajtës vendi mund të zëvendësojë vetëm një varg ose një numër. As një fjalë kyçe, as një identifikues, as pjesë e një vargu ose një grup vargjesh nuk mund të zëvendësohen përmes një mbajtëse vendi. Prandaj, për LIKE duhet së pari të përgatisni të gjithë vargun e kërkimit dhe më pas ta zëvendësoni atë në pyetjen:

$name = "% $emri %" ;
$stm = $pdo -> përgatit ( "ZGJEDH * NGA tabela WHERE emri LIKE ?");
$stm -> ekzekutoni (array($name ));
$data = $stm -> fetchAll();

Epo, e kuptoni idenë. Gjithçka është e keqe edhe këtu. PDO nuk ofron fare mjete për të punuar me identifikues dhe ato duhet të formatohen në mënyrën e vjetër, me dorë (ose, megjithatë, të shikoni drejt SafeMysql, në të cilin kjo, si shumë çështje të tjera, zgjidhet thjesht dhe me elegancë).
Duhet mbajtur mend se rregullat për formatimin e identifikuesve ndryshojnë për baza të ndryshme të të dhënave.

Në mysql, për të formatuar manualisht një identifikues, duhet të bëni dy gjëra:
- mbylle atë në prapavijë ("`").
- kërkoni për këto karaktere brenda identifikuesit duke i dyfishuar.

$field = "`" . str_replace ("`", "``" , $_GET [ "fushë" ]). "`";
$sql = $fushë " ;

Megjithatë, ka një paralajmërim këtu. Vetëm formatimi mund të mos jetë i mjaftueshëm. Kodi i mësipërm na mbron nga injektimi klasik, por në disa raste armiku ende mund të shkruajë diçka të padëshiruar nëse pamenduar zëvendësojmë emrat e fushave dhe tabelave direkt në pyetje. Për shembull, në tabelën e përdoruesve ka një fushë admin. Nëse emrat e fushave hyrëse nuk filtrohen, atëherë çdo budalla do të shkruajë ndonjë gjë të keqe në këtë fushë kur gjeneron automatikisht një kërkesë nga një POST.

Prandaj, këshillohet që të kontrolloni emrat e tabelave dhe fushave që vijnë nga përdoruesi për vlefshmëri, si në shembullin më poshtë

Çdo kod embed që mund të shihet në mësime të shumta sjell melankolinë dhe një dëshirë për të vrarë apstenin. Ndërtime me shumë kilometra me përsëritje të emrave të njëjtë - në indekset $_POST, në emrat e variablave, në emrat e fushave në një kërkesë, në emrat e mbajtësve të vendeve në një kërkesë, në emrat e mbajtësve të vendeve dhe emrat e ndryshoreve kur lidhen.
Duke parë këtë kod më bën të dëshiroj të vras ​​dikë, ose të paktën ta bëj pak më të shkurtër.

Kjo mund të bëhet duke miratuar një konventë që emrat e fushave në formë të përputhen me emrat e fushave në tabelë. Pastaj këta emra mund të renditen vetëm një herë (për të mbrojtur kundër zëvendësimit, i cili u përmend më lart), dhe një funksion i vogël ndihmës mund të përdoret për të mbledhur pyetjen, i cili, për shkak të veçorive të mysql, është i përshtatshëm si për INSERT ashtu edhe për INSERT dhe për të. Përditëso pyetjet:

funksioni pdoSet ($lejuar, & $values, $source = array()) (
$set = "" ;
$values ​​= array();
nëse (! $burim ) $burim = & $_POST ;
foreach ($lejohet si $field) (
nëse (isset($source [ $field ])) (
$set .= "`" . str_replace ("`", "``" , $field ). "`". "=: $field , " ;
$values ​​[ $field ] = $burimi [ $field ];
}
}
kthye substr ($set, 0, - 2);
}

Prandaj, kodi i ngulitjes do të jetë

$allowed = array("emri" , "mbiemri" , "email" ); // fushat e lejuara
$sql = "INSERT NE SET-in e përdoruesve " . pdoSet ($lejohet, $values);
$stm = $dbh -> përgatit ($sql );
$stm -> ekzekutoni ($values);

Dhe për përditësimin - kjo:

$allowed = array("emri" , "mbiemri" , "email" , "fjalëkalimi" ); // fushat e lejuara
$_POST ["fjalëkalim" ] = MD5 ($_POST [ "hyrje" ]. $_POST [ "fjalëkalim" ]);
$sql = "Përditëso SETimin e përdoruesve " . pdoSet ($lejohet, $values). "WHERE id = :id" ;
$stm = $dbh -> përgatit ($sql );
$values ​​["id"] = $_POST ["id"];
$stm -> ekzekutoni ($values);

Jo shumë mbresëlënëse, por shumë efektive. Më lejoni t'ju kujtoj, meqë ra fjala, se nëse përdorni Class për punë të sigurt dhe të përshtatshme me MySQL, atëherë e gjithë kjo bëhet në dy rreshta.

PDO dhe fjalë kyçe
Është e pamundur të dalësh me ndonjë gjë tjetër përveç filtrimit këtu. Prandaj, është marrëzi të ekzekutosh të gjithë operatorët që nuk janë specifikuar drejtpërdrejt në kërkesë përmes listës së bardhë:

$dirs = grup ("ASC" , "DESC" );
$key = array_search ($_GET["dir"], $dirs));
$dir = $urdhra [ $key ];
$sql = "ZGJIDH * NGA `tabela` RENDOSJE NGA$field $dir " ;

Afati PDOështë një shkurtim i konceptit Objektet e të dhënave PHP. Siç sugjeron emri, kjo teknologji ju lejon të punoni me përmbajtjen e bazës së të dhënave përmes objekteve.

Pse jo myqli apo mysql?

Më shpesh, në lidhje me teknologjitë e reja, lind pyetja për avantazhet e tyre ndaj mjeteve të mira të vjetra dhe të provuara, si dhe transferimi i projekteve aktuale dhe të vjetra në to.

PDO orientimi në objekt

PHP po zhvillohet shumë aktivisht dhe përpiqet të bëhet një nga mjetet më të mira për zhvillimin e shpejtë të aplikacioneve në internet në të dy nivelet masive dhe të korporatave.

Duke folur për PHP, nënkuptojmë objekte moderne të orientuara PHP, duke ju lejuar të shkruani kod universal që është i përshtatshëm për testim dhe ripërdorim.

Përdorimi PDO ju lejon të zhvendosni punën e bazës së të dhënave në një nivel të orientuar nga objekti dhe të përmirësoni transportueshmërinë e kodit. Në fakt, përdorimi PDO jo aq e vështirë sa mund të mendohet.

Abstraksioni

Le të imagjinojmë që ne kemi zhvilluar një aplikacion për një kohë të gjatë duke përdorur MySQL. Dhe pastaj, në një moment të mirë, bëhet e nevojshme të zëvendësohet MySQLPostgreSQL.

Së paku, do të na duhet të zëvendësojmë të gjitha telefonatat mysqli_connect() (mysql_connect())pg_connect() dhe, për analogji, funksione të tjera të përdorura për të kërkuar dhe përpunuar të dhëna.

Kur përdorni PDO, do të kufizohemi në ndryshimin e disa parametrave në skedarët e konfigurimit.

Lidhja e parametrave

Përdorimi i parametrave të lidhur siguron fleksibilitet më të madh në hartimin e pyetjeve dhe përmirëson mbrojtjen kundër SQL injeksione.

Marrja e të dhënave si objekte

Ata që tashmë përdorin ORM(hartës relacionale objekt - harta e të dhënave objekt-relacionale), për shembull, Doktrina, di lehtësinë e paraqitjes së të dhënave nga tabelat e bazës së të dhënave në formën e objekteve. PDO ju lejon të merrni të dhëna në formën e objekteve dhe pa përdorur ORM.

Shtesa mysql nuk mbështetet më

Mbështetje shtesë mysql hiqet përgjithmonë nga e reja PHP 7. Nëse planifikoni ta transferoni projektin në version i ri PHP, duhet të përdorni të paktën mysqli në të tani. Sigurisht, është më mirë të filloni të përdorni PDO nëse nuk e keni bërë tashmë.

Më duket se këto arsye janë të mjaftueshme për të përmbysur peshoren në favor të përdorimit PDO. Për më tepër, nuk keni nevojë të instaloni asgjë shtesë.

Kontrollimi i pranisë së PDO në sistem

Versionet PHP 5.5 dhe më e larta, më shpesh, tashmë përmbajnë një shtesë për të punuar me të PDO. Për të kontrolluar, thjesht ekzekutoni një komandë të thjeshtë në tastierë:

php -i | grep "pdo"

Tani le ta hapim atë në çdo shfletues dhe të gjejmë të dhënat e nevojshme duke kërkuar sipas rreshtit PDO.

Njohja me PDO

Procesi i punës me PDO jo shumë i ndryshëm nga ai tradicional. Në përgjithësi, procesi i përdorimit PDO duket si kjo:

  1. Lidhu me bazën e të dhënave;
  2. Nëse është e nevojshme, përgatitni një kërkesë dhe parametrat e lidhjes;
  3. Ekzekutimi i kërkesës.

Lidhja me bazën e të dhënave

Për t'u lidhur me bazën e të dhënave ju duhet të krijoni një objekt të ri PDO dhe kaloni emrin e burimit të të dhënave, i njohur gjithashtu si DSN.

Në përgjithësi, DSN përbëhet nga emri i drejtuesit të ndarë me dy pika nga një varg lidhjeje specifike për secilin drejtues PDO.

Për MySQL, lidhja bëhet si kjo:

$lidhje = PDO e re ("mysql:host=localhost;dbname=mydb;charset=utf8", "root", "root");

$lidhje = PDO e re ( "mysql:host=localhost;dbname=mydb;charset=utf8", "rrënjë", "rrënjë");

Në këtë rast, DSN përmban emrin e shoferit mysql, treguesi i hostit (format i mundshëm host=HOST_NAME:PORT), emri i bazës së të dhënave, kodimi, emri i përdoruesit MySQL dhe fjalëkalimin e tij.

Kërkesat

Ndryshe nga mysqli_query (), V PDO ka dy lloje kërkesash:

  • Kthimi i rezultatit ( zgjedh, trego);
  • Nuk kthen rezultat ( fut, detaj dhe të tjerët).

Para së gjithash, le të shqyrtojmë opsionin e dytë.

Ekzekutimi i pyetjeve

Le të shohim një shembull të ekzekutimit të një kërkese duke përdorur shembullin fut.

$connection->exec("INSERT INTO users VALUES (1, "somevalue"");

$connection -> exec () ;

Sigurisht, kjo pyetje kthen numrin e rreshtave të prekur dhe mund ta shihni si më poshtë.

$affectedRows = $connection->exec("INSERT INTO users VALUES (1, "somevalue""); echo $affectedRows;

$affectedRows = $connection -> exec ( "INSERT INTO VALUES të përdoruesve (1, "somevalue"") ;

echo $affectedRows ;

Marrja e rezultateve të pyetjeve

Në rast përdorimi mysqli_query (), kodi mund të jetë si më poshtë.

$rezultat = mysql_query("SELECT * FROM përdoruesit"); while($row = mysql_fetch_assoc($result)) (echo $row["id"] . " " . $row["name"]; )

$result = mysql_query ("SELECT * FROM përdoruesit" );

ndërsa ($row = mysql_fetch_assoc ($rezultat)) (

Për PDO, kodi do të jetë më i thjeshtë dhe më konciz.

foreach($connection->query("SELECT * FROM users") as $row) (echo $row["id"] . " " . $row["name"]; )

foreach ($connection -> pyetje ("SELECT * FROM users") si $row ) (

echo $row [ "id" ] . " " . $row["emri"];

Mënyrat e marrjes së të dhënave

Si në mysqli, PDO ju lejon të merrni të dhëna në mënyra të ndryshme. Për të përcaktuar mënyrën, klasa PDO përmban konstantet përkatëse.

  • PDO::FETCH_ASSOC— kthen një grup të indeksuar me emrin e kolonës në tabelën e bazës së të dhënave;
  • PDO::FETCH_NUM— kthen një grup të indeksuar sipas numrit të kolonës;
  • PDO::FETCH_OBJ- kthen një objekt anonim me emra pronash që korrespondojnë me emrat e kolonave. Për shembull, $row->id do të përmbajë vlerën nga kolona id.
  • PDO::FETCH_CLASS— kthen një shembull të ri të klasës, me vlerat e vetive që korrespondojnë me të dhënat nga rreshti i tabelës. Nëse parametri është i specifikuar PDO::FETCH_CLASSTYPE(Për shembull PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE

), emri i klasës do të përcaktohet nga vlera e kolonës së parë. Shënim : nuk eshte listën e plotë

, të gjitha konstantet e mundshme dhe opsionet për kombinimin e tyre janë të disponueshme në dokumentacion.

Një shembull i marrjes së një grupi shoqërues:

$statement = $connection->pyetës("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_ASSOC)) (echo $row["id"] . " " . $row["name"]; )

$statement = $lidhje ->

echo $row [ "id" ] . " " . $row["emri"];

), emri i klasës do të përcaktohet nga vlera e kolonës së parë. ndërsa ($row = $statement -> fetch (PDO::FETCH_ASSOC) ) ( : Rekomandohet të specifikoni gjithmonë mënyrën e marrjes së mostrave sepse modaliteti PDO::FETCH_BOTH

do të kërkojë dy herë më shumë memorie - në fakt, do të krijohen dy vargje, shoqëruese dhe të rregullta. PDO::FETCH_CLASS Merrni parasysh përdorimin e mënyrës së marrjes së mostrave . Le të krijojmë një klasë:

Përdoruesi

Përdoruesi i klasës ( $id i mbrojtur; emri i mbrojtur i $; funksioni publik getId() (kthimi i $this->id; ) funksioni publik setId($id) ( $this->id = $id; ) funksioni publik getName() (kthimi $this->name ) funksioni publik setName($name) ($this->name = $name;) )

Përdoruesi i klasës

i mbrojtur $id ;

i mbrojtur $emri ;

ktheje $this -> id ;

SetId i funksionit publik ($id)

$this -> id = $id ;

funksioni publik getName()

ktheje $this -> emrin ;

funksioni publik setName ($name)

$this -> emri = $emri ;

Tani le të zgjedhim të dhënat dhe t'i shfaqim të dhënat duke përdorur metodat e klasës:

$statement = $connection->pyetës("SELECT * FROM users"); while($row = $statement->fetch(PDO::FETCH_CLASS, "User")) (echo $row->getId() . " " . $row->getName(); )

$statement = $connection -> pyetje ("SELECT * FROM users" ) ;

ndërsa ($row = $statement -> fetch (PDO::FETCH_CLASS, "User") ) (

echo $row -> getId() . " " . $row -> getName () ;

Pyetjet e përgatitura dhe lidhja e parametrave

Për të kuptuar thelbin dhe të gjitha përfitimet e lidhjes së parametrave, duhet të shikoni më nga afër mekanizmat PDO. Kur telefononi $statement -> query() në kodin e mësipërm, PDO do të përgatisë një kërkesë, do ta ekzekutojë dhe do të kthejë rezultatin.

Kur telefononi $connection -> përgatit () krijohet një kërkesë e përgatitur. Pyetjet e përgatitura janë aftësia e një sistemi të menaxhimit të bazës së të dhënave për të marrë një shabllon pyetësor, për ta përpiluar atë dhe për ta ekzekutuar atë pas marrjes së vlerave të variablave të përdorur në shabllon. Motorët e shabllonit punojnë në të njëjtën mënyrë. I zgjuar Dhe Degëz.

Kur telefononi $statement -> execute() vlerat për zëvendësim transferohen në shabllonin e pyetjes dhe DBMS ekzekuton pyetjen. Ky veprim është i ngjashëm me thirrjen e funksionit të motorit të shabllonit render ().

Një shembull i përdorimit të pyetjeve të përgatitura në PHP PDO:

Në kodin e mësipërm, përgatitet një kërkesë për zgjedhjen e një regjistrimi me një fushë id e barabartë me vlerën që do të zëvendësohet : id. Aktiv në këtë fazë DBMS do të analizojë dhe përpilojë kërkesën, ndoshta duke përdorur caching (në varësi të cilësimeve).

Tani ju duhet të kaloni parametrin që mungon dhe të ekzekutoni kërkesën:

$id = 5; $statement->ekzekutoni([ ":id" => $id ]);

Përfitimet e përdorimit të parametrave të lidhur

Ndoshta, pas shqyrtimit të mënyrës sesi funksionojnë pyetjet e përgatitura dhe parametrave të lidhur, përfitimet e përdorimit të tyre bëhen të dukshme.

PDO ofron një mënyrë të përshtatshme për t'i shpëtuar të dhënave të përdoruesit, për shembull, kodi i tillë nuk është më i nevojshëm:

Në vend të kësaj, tani ka kuptim ta bëni këtë:

Ju madje mund ta shkurtoni më tej kodin duke përdorur parametra të numëruar në vend të atyre me emër:

Në të njëjtën kohë, përdorimi i pyetjeve të përgatitura përmirëson performancën kur përdoret i njëjti shabllon pyetjesh disa herë. Një shembull i zgjedhjes së pesë përdoruesve të rastësishëm nga një bazë të dhënash:

$numberOfUsers = $connection->pyetës("SELECT COUNT(*) FROM users")->fetchColumn(); $përdorues = ; $statement = $connection->prepare("SELECT * FROM users WHERE id = ? LIMIT 1"); për ($i = 1; $i<= 5; $i++) { $id = rand(1, $numberOfUsers); $users = $statement->ekzekutoj([$id])->fetch(PDO::FETCH_OBJ); )

$numberOfUsers = $connection -> pyetje ("SELECT COUNT(*) FROM users" ) -> fetchColumn () ;

$përdorues = ;

për ($i = 1; $i<= 5 ; $i ++ ) {

$id = rand (1 , $numberOfUsers ) ;

$users = $statement -> execute ([ $id ] ) -> fetch (PDO::FETCH_OBJ ) ;

Kur thirrni një metodë përgatit (), DBMS do të analizojë dhe përpilojë kërkesën, duke përdorur caching nëse është e nevojshme. Më vonë gjatë ciklit për, kampionohen vetëm të dhënat me parametrin e specifikuar. Kjo qasje ju lejon të rikuperoni të dhënat më shpejt, duke reduktuar kohën e funksionimit të aplikacionit.

Pas marrjes numri total përdoruesit në metodën e bazës së të dhënave është përdorur fetchColumn(). Kjo metodë merr vlerën e një kolone të vetme dhe është e dobishme kur merren vlera skalare të tilla si vlerat numërimi, shuma, maksimale ose minimale.

Vlerat e kufizuara dhe operatori IN

Shpesh, kur filloni të punoni me PDO, lindin vështirësi me operatorin . Për shembull, imagjinoni që përdoruesi fut disa emra të ndarë me presje. Hyrja e përdoruesit ruhet në një variabël $emra.

Shumica e bazave të të dhënave mbështesin konceptin e pyetjeve të përgatitura. Çfarë është ajo? Kjo mund të përshkruhet si një lloj modeli i pyetësorit të përpiluar SQL që do të ekzekutohet nga aplikacioni dhe do të konfigurohet duke përdorur parametrat e hyrjes. Pyetjet e përgatitura kanë dy përparësi kryesore:

  • Kërkesa duhet të përgatitet një herë dhe më pas mund të ekzekutohet sa herë të jetë e nevojshme, me parametra të njëjtë dhe të ndryshëm.
  • Parametrat e përgatitur të pyetjes nuk kanë nevojë të shmangen me thonjëza; shoferi e bën këtë automatikisht. Nëse aplikacioni përdor vetëm pyetje të përgatitura, zhvilluesi mund të jetë i sigurt se nuk mund të ndodhin injeksione SQL (megjithatë, nëse pjesët e tjera të trupit të pyetjes shkruhen me karaktere të pashkruara, injeksionet SQL janë ende të mundshme; ne po flasim për parametra këtu).

Pyetjet e përgatitura janë gjithashtu të dobishme sepse PDO mund t'i imitojë ato nëse drejtuesi i bazës së të dhënave nuk ka funksione të ngjashme. Kjo do të thotë që aplikacioni mund të përdorë të njëjtën teknikë të aksesit të të dhënave pavarësisht nga aftësitë e DBMS.

Shembulli #1 Futje të përsëritura në një bazë të dhënash duke përdorur pyetje të përgatitura

emri Dhe vlerë, të cilat zëvendësohen në vend të pseudovariablave përkatëse:

$stmt = $dbh -> përgatit ( "FUT NË REGJISTRI (emri, vlera) VLERAT (:name, :value)");
$stmt -> bindParam (":name" , $name );
$stmt -> bindParam (":value" , ​​$value);

// fut një rresht
$name = "një" ;
$value = 1 ;
$stmt -> execute();

$name = "dy" ;
$value = 2 ;
$stmt -> execute();
?>

Shembulli #2 Futje të përsëritura në një bazë të dhënash duke përdorur pyetje të përgatitura

Në këtë shembull, pyetja INSERT ekzekutohet 2 herë me kuptime të ndryshme emri Dhe vlerë të cilat zëvendësohen në vend të pseudovariablave ? .

$stmt = $dbh -> përgatit ( "FUT NË REGJISTRI (emri, vlera) VLERAT (?, ?)");
$stmt -> bindParam(1, $name);
$stmt -> bindParam (2 , $value );

// fut një rresht
$name = "një" ;
$value = 1 ;
$stmt -> execute();

// tani një rresht tjetër me vlera të ndryshme
$name = "dy" ;
$value = 2 ;
$stmt -> execute();
?>

Shembulli #3 Marrja e të dhënave duke përdorur pyetje të përgatitura

Në këtë shembull, bëhet një përzgjedhje nga baza e të dhënave duke përdorur një çelës që përdoruesi fut përmes formularit. Hyrja e përdoruesit citohet automatikisht, kështu që nuk ka rrezik të injektimit SQL.

Nëse DBMS mbështet parametrat e daljes, aplikacioni mund t'i përdorë ato në të njëjtën mënyrë si ato hyrëse. Parametrat e daljes zakonisht përdoren për të marrë të dhëna nga procedurat e ruajtura. Përdorimi i parametrave të daljes është disi më i vështirë, pasi zhvilluesi duhet të dijë madhësinë maksimale të vlerave të nxjerra në fazën e vendosjes së këtyre parametrave. Nëse vlera e marrë është më e madhe se sa pritej, do të shfaqet një gabim.

Shembulli #4 Thirrja e një procedure të ruajtur me parametrat e daljes

$stmt = $dbh -> përgatit ("CALL sp_returns_string(?)" );
$stmt -> bindParam(1, $return_value, PDO::PARAM_STR, 4000);

// thirrni një procedurë të ruajtur
$stmt -> execute();

shtypur "u kthye procedura$return_value \n" ;
?>

Ju mund të vendosni një parametër që të jetë edhe hyrje edhe dalje; Sintaksa është e njëjtë si për parametrat e daljes. Shembulli i mëposhtëm kalon vargun "hello" në procedurën e ruajtur, dhe më pas vargu do të zëvendësohet me vlerën e kthyer.

Shembulli #5 Thirrja e një procedure të ruajtur me një parametër hyrje/dalje

$stmt = $dbh -> përgatit ( "THIRRJE sp_takes_string_returns_string(?)");
$value = "përshëndetje" ;!}
$stmt -> bindParam (1 , $value , PDO :: PARAM_STR | PDO :: PARAM_INPUT_OUTPUT , 4000 );

// thirrni një procedurë të ruajtur
$stmt -> execute();

shtypur "u kthye procedura$value\n" ;
?>

(array ("% $_GET [emri ] %" ));
?>