PDO vs. MySQLi Care ar trebui să utilizați?

Când accesăm o bază de date în PHP, avem două opțiuni: MySQLi și DOP. Deci, ce ar trebui să știți înainte de a alege unul? Diferențele, suportul bazei de date, stabilitatea și preocupările legate de performanță vor fi prezentate în acest articol.

Dacă lucrați frecvent cu baze de date în PHP, este posibil să doriți să verificați gama de scripturi și aplicații utile atât pentru MySQLi cât și pentru PDO pe Envato Market.

PDO aplicații pe Envato Market

rezumat

DOP MySQLi
Suport pentru baze de date 12 diferiți șoferi Numai MySQL
API-ul OOP OOP + procedural
Conexiune Uşor Uşor
Parametrii numiți da Nu
Cartografierea obiectelor da da
Întrebări pregătite
(partea clientului)
da Nu
Performanţă Rapid Rapid
Proceduri stocate da da

Conexiune

Este un cinch să vă conectați la o bază de date cu ambele:

// PDO $ pdo = nou PDO ("mysql: host = localhost; dbname = bază de date", "nume de utilizator", "parolă"); // mysqli, modul procedural $ mysqli = mysqli_connect ('localhost', 'username', 'password', 'database'); // mysqli, modul orientat pe obiecte $ mysqli = mysqli nou ('localhost', 'username', 'password', 'database');

Rețineți că aceste obiecte / resurse de conectare vor fi considerate ca existente în restul acestui tutorial.


Suport API

Atât PDO, cât și MySQLi oferă un API orientat pe obiecte, dar MySQLi oferă de asemenea un API procedural - ceea ce ușurează înțelegerea noilor veniți. Dacă sunteți familiarizat cu driver-ul nativ PHP MySQL, veți găsi migrarea la interfața procedurală MySQLi mult mai ușor. Pe de altă parte, odată ce master DOP, îl puteți folosi cu orice bază de date dorită!


Suport pentru baze de date

Avantajul principal al PDO asupra MySQLi este suportul pentru driverul bazei de date. La momentul acestei scrieri, DOP sprijină 12 drivere diferite, spre deosebire de MySQLi, care suportă Numai MySQL.

Pentru a imprima o listă a tuturor driverelor care acceptă în prezent PDO, utilizați următorul cod:

var_dump (DOP :: getAvailableDrivers ());

Ce inseamna asta? În situațiile în care trebuie să vă schimbați proiectul pentru a utiliza o altă bază de date, DOP face procesul transparent. Asa de tot ce trebuie să faci este schimbarea șirului de conectare și câteva interogări - dacă utilizează metode care nu sunt acceptate de noua dvs. bază de date. Cu MySQLi, va trebui rescrie fiecare bucata de cod - interogări incluse.


Parametrii denumiți

Aceasta este o altă caracteristică importantă pe care o are DOP; parametrii de legare sunt mult mai ușor decât folosind legarea numerică:

$ params = array (': username' => 'test', ': email' => $ mail, ': last_login' => timp () - 3600); $ pdo-> prepare ('SELECT * FROM utilizatori WHERE username =: username AND email =: email AND last_login>: last_login'); $ Pdo-> executa ($ params);

... opuse modului MySQLi:

$ query = $ mysqli-> prepare ('SELECT * FROM users WHERE username =? AND email =? AND last_login>?'); $ query-> bind_param ('sss', 'test', $ mail, time () - 3600); $ Query-> execute ();

Legarea parametrilor de semnalizare poate părea mai scurtă, dar nu este la fel de flexibilă ca parametrii numiți, datorită faptului că dezvoltatorul trebuie să întotdeauna urmăriți ordinea parametrilor; se simte "hacky" în anumite circumstanțe.

din pacate, MySQLi nu acceptă parametrii numiți.


Cartografierea obiectelor

Atât PDO, cât și MySQLi pot afișa rezultatele obiectelor. Acest lucru vine la îndemână dacă nu doriți să utilizați un strat de bază de abstractizare personalizată a bazei de date, dar totuși doriți ca un comportament asemănător ORM. Să ne imaginăm că avem a Utilizator clasă cu unele proprietăți, care se potrivesc cu numele câmpurilor dintr-o bază de date.

utilizator de clasă public $ id; public $ first_name; public $ last_name; funcția publică funcția () return '#'. $ this-> id. ':'. $ this-> first_name. ". $ this-> last_name;

Fără cartografiere a obiectelor, ar trebui să umplem valorile fiecărui câmp (fie manual, fie prin constructor) înainte de a putea folosi info () corectă.

Acest lucru ne permite să predefinim aceste proprietăți înainte ca obiectul să fie construit! De exemplu:

$ query = "SELECT id, first_name, last_name FROM utilizatori"; // PDO $ rezultat = $ pdo-> interogare ($ interogare); $ result-> setFetchMode (PDO :: FETCH_CLASS, 'Utilizator'); în timp ce ($ user = $ result-> fetch ()) echo $ user-> info (). "  // MySQLI, modul procedural dacă ($ result = mysqli_query ($ mysqli, $ query)) în timp ($ user = mysqli_fetch_object ($ result, 'User')) echo $ user-> info (). „;  // MySQLi, modul orientat pe obiecte dacă ($ result = $ mysqli-> query ($ query)) în timp ce ($ user = $ result-> fetch_object (' . "\ n"; 

Securitate

Ambele biblioteci oferă Securitatea injecțiilor SQL, atâta timp cât dezvoltatorul le folosește așa cum au fost intenționate (citiți: ieșirea / legarea parametrilor cu instrucțiunile pregătite).

Să spunem că un hacker încearcă să injecteze niște SQL rău intenționat prin parametrul de interogare HTTP "username" (GET):

$ _GET ['username'] = ''; DELETE FROM users; / * "

Dacă nu reușim să scăpăm de acest lucru, acesta va fi inclus în interogarea "ca atare" - ștergerea tuturor rândurilor din utilizatori tabel (atât PDO cât și mysqli acceptă interogări multiple).

// PDO, "manual" scăpând $ username = PDO :: quote ($ _GET ['username']); $ pdo-> interogare ("SELECT * FROM users WHERE username = $ username"); // mysqli, "manual" scăpând $ username = mysqli_real_escape_string ($ _GET ['username']); $ mysqli-> interogare ("SELECT * FROM users WHERE username = '$ username'");

După cum puteți vedea, DOP :: citat () nu numai că scapă de șir, ci și îl citează. Pe cealaltă parte, mysqli_real_escape_string () va scăpa numai de șir; va trebui să aplicați manual ghilimele.

// PDO, instrucțiunea pregătită $ pdo-> prepare ('SELECT * FROM users WHERE username =: username'); $ pdo-> execute (array (': username' => $ _GET ['username'])); // mysqli, pregătite instrucțiuni $ query = $ mysqli-> prepare ('SELECT * FROM users WHERE username =?'); $ query-> bind_param ('s', $ _GET ['username']); $ Query-> execute ();

Vă recomandăm să utilizați întotdeauna instrucțiuni pregătite cu interogări legate în loc de PDO :: citat () și mysqli_real_escape_string ().


Performanţă

În timp ce atât PDO, cât și MySQLi sunt destul de rapide, MySQLi are performanțe nesemnificative mai rapide - <2,5% pentru declarațiile nepregătite și ~ 6,5% pentru cele pregătite. Cu toate acestea, extensia MySQL nativă este chiar mai rapidă decât ambele. Deci, dacă într-adevăr trebuie să stoarceți fiecare ultimă bucată de performanță, acesta este un lucru pe care îl puteți lua în considerare.


rezumat

În cele din urmă, DOP câștigă cu ușurință această luptă. Cu suport pentru douăsprezece drivere de baze de date diferite (optsprezece baze de date diferite!) Și parametrii numiți, putem ignora pierderea de performanță mică și obișnuiți-vă cu API-ul său. Din punct de vedere al securității, ambele sunt în siguranță, atâta timp cât dezvoltatorul le folosește așa cum ar trebui să fie folosite (citiți: declarații pregătite).

Deci, dacă mai lucrați cu MySQLi, poate că este timpul pentru o schimbare!

Cod