Abbiamo trattato l'API PDO di PHP un paio di volte qui su Nettuts +, ma, in generale, quegli articoli si sono concentrati maggiormente sulla teoria e meno sull'applicazione. Questo articolo lo risolverà!
Per dirla chiaramente, se usi ancora PHP di vecchia data mysql
API per connettersi ai tuoi database, continua a leggere!
Se stai lavorando con PHP o MySQL e hai bisogno di una soluzione rapida per un errore nel tuo codice, puoi fare in modo che ogni singolo errore venga risolto rapidamente e in modo economico dallo sviluppatore PHP Araneux su Envato Studio.
È possibile che, a questo punto, l'unico pensiero nella tua mente sia: "Che diamine è DOP?" Bene, è una delle tre API disponibili di PHP per la connessione a un database MySQL. "Tre", dici? Sì; molte persone non lo sanno, ma ci sono tre diverse API per la connessione:
mysql
mysqli
- Migliorato MySQLpdo
- Oggetti dati PHPIl tradizionale mysql
L'API sicuramente svolge il suo lavoro ed è diventata così popolare in gran parte grazie al fatto che rende il processo di recupero di alcuni record da un database il più semplice possibile. Per esempio:
/ * * Anti-Pattern * / # Connetti mysql_connect ('localhost', 'username', 'password') o die ('Impossibile connettersi:'. Mysql_error ()); # Scegli un database mysql_select_db ('someDatabase') o die ('Could not select database'); # Esegue query del database $ query = "SELECT * from someTable"; $ result = mysql_query ($ query) o die ('Query failed:'. mysql_error ()); # Filtra attraverso le righe ed echo le informazioni desiderate mentre ($ row = mysql_fetch_object ($ result)) echo $ row-> name;
Sì, il codice sopra è abbastanza semplice, ma viene fornito con la sua significativa percentuale di aspetti negativi.
PDO, o PHP Data Objects, fornisce un'API più potente a cui non interessa il driver che usi; è indipendente dal database. Inoltre, offre la possibilità di utilizzare istruzioni preparate, eliminando praticamente qualsiasi preoccupazione relativa all'iniezione SQL. Scopri la gamma di script e app PDO su Envato Market per avere un'idea di cosa è possibile.
Quando ho iniziato a conoscere l'API PDO, devo ammettere che era leggermente intimidatorio. Questo non era perché l'API era eccessivamente complicata (non lo è) - è solo che il vecchio myqsl
L'API era così facile da usare!
Non preoccuparti, però; segui questi semplici passaggi e sarai subito operativo.
Quindi conosci già il modo legacy di connettersi a un database MySQL:
# Connetti mysql_connect ('localhost', 'username', 'password') o die ('Impossibile connettersi:'. Mysql_error ());
Con PDO, creiamo una nuova istanza della classe e specificiamo il driver, il nome del database, il nome utente e la password, così:
$ conn = nuovo PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password);
Non lasciare che questa lunga stringa ti confonda; è davvero molto semplice: specifichiamo il nome del driver (mysql, in questo caso), seguito dai dettagli richiesti (stringa di connessione) per il collegamento ad esso.
La cosa bella di questo approccio è che, se preferiamo utilizzare un database SQLite, semplicemente aggiorniamo il DSN, o "Nome origine dati", di conseguenza; non dipendiamo da MySQL nel modo in cui siamo quando le funzioni di utilizzo, come mysql_connect
.
Ma, cosa succede se c'è un errore e non possiamo connetterci al database? Bene, avvolgiamo tutto dentro a prova a prendere
bloccare:
prova $ conn = nuovo PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); catch (PDOException $ e) echo 'ERRORE:'. $ E-> getMessage ();
Così va meglio! Si noti che, per impostazione predefinita, la modalità di errore predefinita per PDO è PDO :: ERRMODE_SILENT
. Con questa impostazione lasciata invariata, dovrai recuperare manualmente gli errori, dopo aver eseguito una query.
echo $ conn-> errorCode (); echo $ conn-> errorInfo ();
Invece, una scelta migliore, durante lo sviluppo, è di aggiornare questa impostazione a PDO :: ERRMODE_EXCEPTION
, che genererà eccezioni nel momento in cui si verificano. In questo modo, tutte le eccezioni non risolte fermeranno la sceneggiatura.
Per riferimento, le opzioni disponibili sono:
PDO :: ERRMODE_SILENT
PDO :: ERRMODE_WARNING
PDO :: ERRMODE_EXCEPTION
A questo punto, abbiamo creato una connessione al database; prendiamo alcune informazioni da esso. Esistono due modi principali per eseguire questo compito: domanda
e eseguire
. Li esamineremo entrambi.
/ * * Il metodo di ricerca * Anti-Pattern * / $ name = 'Joe'; # dati forniti dall'utente provare $ conn = nuovo PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ data = $ conn-> query ('SELECT * FROM myTable WHERE name ='. $ conn-> quote ($ name)); foreach ($ data come $ row) print_r ($ row); catch (PDOException $ e) echo 'ERRORE:'. $ E-> getMessage ();
Sebbene funzioni, notiamo che stiamo ancora eseguendo manualmente l'escape dei dati dell'utente con PDO :: citazione
metodo. Pensa a questo metodo come, più o meno, l'equivalente della PDO da usare mysql_real_escape_string
; entrambi scapperanno e citeranno la stringa che gli passi. In situazioni, quando si vincolano dati forniti dall'utente a una query SQL, si consiglia vivamente di utilizzare invece istruzioni preparate. Detto questo, se le query SQL non dipendono dai dati del modulo, il domanda
il metodo è una scelta utile e rende il processo di looping dei risultati facile come un per ciascuno
dichiarazione.
/ * * Il metodo di istruzioni preparate * Best Practice * / $ id = 5; prova $ conn = nuovo PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ conn-> prepare ('SELECT * FROM myTable WHERE id =: id'); $ stmt-> execute (array ('id' => $ id)); while ($ row = $ stmt-> fetch ()) print_r ($ row); catch (PDOException $ e) echo 'ERRORE:'. $ E-> getMessage ();
In questo esempio, stiamo usando il preparare
metodo per, letteralmente, preparare la query, prima che i dati dell'utente siano stati allegati. Con questa tecnica, l'iniezione SQL è praticamente impossibile, perché i dati non vengono mai inseriti nella query SQL stessa. Si noti che, al contrario, utilizziamo parametri denominati (: id
) per specificare i segnaposto.
In alternativa, puoi usare
?
parametri, tuttavia, rende un'esperienza meno leggibile. Rimani con i parametri denominati.
Successivamente, eseguiamo la query, passando una matrice, che contiene i dati che dovrebbero essere associati a quei segnaposto.
$ stmt-> execute (array ('id' => $ id));
Un approccio alternativo, ma perfettamente accettabile, sarebbe quello di utilizzare il BindParam
metodo, così:
$ stmt-> bindParam (': id', $ id, PDO :: PARAM_INT); $ Stmt-> execute ();
Dopo aver chiamato il eseguire
metodo, ci sono diversi modi per ricevere i dati: una matrice (il valore predefinito), un oggetto, ecc. Nell'esempio sopra, viene utilizzata la risposta predefinita: PDO :: FETCH_ASSOC
; questo può essere facilmente ignorato, tuttavia, se necessario:
while ($ row = $ stmt-> fetch (PDO :: FETCH_OBJ)) print_r ($ row);
Ora, abbiamo specificato che vogliamo interagire con il set di risultati in un modo più orientato agli oggetti. Le scelte disponibili includono, ma non sono limitate a:
Un problema con il codice sopra riportato è che non stiamo fornendo alcun feedback, se non vengono restituiti risultati. Risolviamo questo:
$ stmt-> execute (array ('id' => $ id)); # Ottieni array contenente tutte le righe del risultato $ result = $ stmt-> fetchAll (); # Se sono state restituite una o più righe ... if (count ($ result)) foreach ($ result as $ row) print_r ($ row); else echo "Nessuna riga restituita.";
A questo punto, il nostro codice completo dovrebbe apparire così:
$ id = 5; prova $ conn = nuovo PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ stmt = $ conn-> prepare ('SELECT * FROM myTable WHERE id =: id'); $ stmt-> execute (array ('id' => $ id)); $ result = $ stmt-> fetchAll (); if (count ($ result)) foreach ($ result as $ row) print_r ($ row); else echo "Nessuna riga restituita."; catch (PDOException $ e) echo 'ERRORE:'. $ E-> getMessage ();
L'estensione PDO diventa particolarmente potente quando si esegue la stessa query SQL più volte, ma con parametri diversi.
prova $ conn = nuovo PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); # Prepara la query ONCE $ stmt = $ conn-> prepare ('INSERT INTO someTable VALUES (: name)'); $ stmt-> bindParam (': name', $ name); # Primo inserimento $ name = 'Keith'; $ Stmt-> execute (); # Secondo inserimento $ name = 'Steven'; $ Stmt-> execute (); catch (PDOException $ e) echo $ e-> getMessage ();
Una volta che la query è stata preparata, può essere eseguita più volte, con parametri diversi. Il codice sopra inserirà due righe nel database: una con il nome di "Kevin" e l'altra "Steven".
Ora che hai avviato il processo di base, esaminiamo rapidamente le varie attività CRUD. Come scoprirai, il codice richiesto per ciascuno è praticamente identico.
prova $ pdo = nuovo PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ pdo-> prepare ('INSERT INTO someTable VALUES (: name)'); $ stmt-> execute (array (': name' => 'Justin Bieber')); # Righe interessate? echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) echo 'Error:'. $ E-> getMessage ();
$ id = 5; $ name = "Joe the Plumber"; prova $ pdo = nuovo PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ pdo-> prepare ('UPDATE someTable SET name =: name WHERE id =: id'); $ stmt-> execute (array (': id' => $ id, ': name' => $ name)); echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) echo 'Error:'. $ E-> getMessage ();
$ id = 5; // Da una forma o qualcosa di simile prova $ pdo = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ pdo-> prepare ('DELETE FROM someTable WHERE id =: id'); $ stmt-> bindParam (': id', $ id); // questa volta, useremo il metodo bindParam $ stmt-> execute (); echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) echo 'Error:'. $ E-> getMessage ();
Uno degli aspetti più netti di PDO (anche mysqli) è che ci dà la possibilità di mappare i risultati dell'interrogazione su un'istanza o un oggetto di classe. Ecco un esempio:
class User public $ first_name; public $ last_name; public function full_name () return $ this-> first_name. ". $ this-> last_name; prova $ pdo = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ result = $ pdo-> query ('SELECT * FROM someTable'); # Map results to object $ result-> setFetchMode (PDO :: FETCH_CLASS, "Utente") while ($ utente = $ risultato-> fetch ()) # Chiama il nostro metodo full_name personalizzato echo $ user-> full_name (); catch (PDOException $ e) echo 'Errore:'. $ e-> getMessage ();
In conclusione: se stai ancora usando quel vecchio mysql
API per la connessione ai tuoi database, stop. Sebbene non sia stato ancora deprecato, in termini di istruzione e documentazione, potrebbe anche essere. Il codice sarà significativamente più sicuro e snellito se si adotta l'estensione PDO. Controlla gli articoli DOP su Envato Market per vedere cosa puoi fare.