PHP-Datenbankzugriff Machen Sie es richtig?

Wir haben hier mehr über die PDO-API von PHP auf Nettuts + berichtet, aber im Allgemeinen konzentrierten sich diese Artikel eher auf die Theorie und weniger auf die Anwendung. Dieser Artikel wird das beheben!

Um es einfach auszudrücken, wenn Sie noch PHP von Grund auf verwenden Mysql API für die Verbindung zu Ihren Datenbanken, lesen Sie weiter!

Suche nach einer Verknüpfung?

Wenn Sie mit PHP oder MySQL arbeiten und eine schnelle Fehlerbehebung in Ihrem Code benötigen, können Sie jeden einzelnen Fehler schnell und kostengünstig vom PHP-Entwickler Araneux in Envato Studio beheben lassen.


Was?

Es ist möglich, dass zu diesem Zeitpunkt der einzige Gedanke in Ihrem Kopf ist: "Was zum Teufel ist PDO?" Nun, es ist eine der drei verfügbaren APIs von PHP für die Verbindung zu einer MySQL-Datenbank. "Drei", sagst du? Ja; Viele Leute wissen es nicht, aber es gibt drei verschiedene APIs für die Verbindung:

  • Mysql
  • Mysqli - MySQL verbessert
  • pdo - PHP-Datenobjekte

Das traditionelle Mysql Die API erledigt die Aufgabe sicherlich und ist vor allem deshalb so beliebt, weil sie das Abrufen einiger Datensätze aus einer Datenbank so einfach wie möglich macht. Zum Beispiel:

/ * * Anti-Pattern * / # Verbinde mysql_connect ('localhost', 'username', 'password') oder die ('Konnte nicht verbinden:'. Mysql_error ()); # Wählen Sie eine Datenbank aus mysql_select_db ('someDatabase') oder die ('Datenbank konnte nicht ausgewählt werden'); # Datenbankabfrage ausführen $ query = "SELECT * from someTable"; $ result = mysql_query ($ query) oder die ('Abfrage fehlgeschlagen:'. mysql_error ()); # Filtern Sie durch Zeilen und geben Sie die gewünschten Informationen ein, während ($ row = mysql_fetch_object ($ result)) echo $ row-> name; 

Ja, der obige Code ist ziemlich einfach, hat aber einen erheblichen Anteil an Nachteilen.

  • Veraltet: Obwohl es aufgrund der weitverbreiteten Verwendung im Hinblick auf bewährte Verfahren und Ausbildung nicht offiziell abgelehnt wurde, könnte es genauso gut sein.
  • Flucht: Der Prozess der Flucht von Benutzereingaben bleibt dem Entwickler überlassen - viele davon verstehen oder wissen nicht, wie sie die Daten bereinigen.
  • Flexibilität: Die API ist nicht flexibel. Der obige Code ist auf die Arbeit mit einer MySQL-Datenbank zugeschnitten. Was ist, wenn Sie wechseln??

PDO oder PHP Data Objects bietet eine leistungsfähigere API, die sich nicht für den verwendeten Treiber interessiert. es ist Datenbank-Agnostiker. Darüber hinaus bietet es die Möglichkeit, vorbereitete Anweisungen zu verwenden, wodurch die Sorge um die SQL-Injection praktisch beseitigt wird. Sehen Sie sich die Palette der PDO-Skripts und Apps im Envato Market an, um sich ein Bild von den Möglichkeiten zu machen.


Wie?

Als ich zum ersten Mal etwas über die PDO-API erfuhr, muss ich zugeben, dass es etwas einschüchternd war. Das lag nicht daran, dass die API zu kompliziert war (es ist nicht so) - es ist nur das Alte myqsl API war so einfach zu bedienen!

Mach dir keine Sorgen; Folgen Sie diesen einfachen Schritten, und Sie sind in kürzester Zeit einsatzbereit.

Verbinden

Sie kennen also bereits die Art und Weise, wie Sie eine Verbindung zu einer MySQL-Datenbank herstellen:

# Verbinden Sie mysql_connect ('localhost', 'username', 'password') oder die ('Konnte keine Verbindung herstellen:'. Mysql_error ());

Mit PDO erstellen wir eine neue Instanz der Klasse und geben den Treiber, den Datenbanknamen, den Benutzernamen und das Kennwort an - wie folgt:

$ conn = new PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password);

Lass dich nicht von dieser langen Schnur verwirren; Es ist wirklich sehr einfach: Wir geben den Namen des Treibers (in diesem Fall MySQL) an, gefolgt von den erforderlichen Details (Verbindungszeichenfolge), um eine Verbindung herzustellen.

Das Schöne an diesem Ansatz ist, dass wir, wenn wir stattdessen eine sqlite-Datenbank verwenden möchten, einfach den DSN oder "Data Source Name" (Datenquellenname) entsprechend aktualisieren. Wir sind nicht so abhängig von MySQL, wie wir es tun, wenn Sie Funktionen wie verwenden mysql_connect.

Fehler

Was aber, wenn ein Fehler vorliegt und wir keine Verbindung zur Datenbank herstellen können? Nun, lass uns alles in eine packen versuchen / fangen Block:

try $ conn = new PDO ('mysql: host = localhost; dbname = myDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION);  catch (PDOException $ e) Echo 'ERROR:'. $ e-> getMessage (); 

Das ist besser! Bitte beachten Sie, dass standardmäßig der Standardfehlermodus für PDO ist PDO :: ERRMODE_SILENT. Wenn diese Einstellung nicht geändert wird, müssen Sie nach einer Abfrage die Fehler manuell abrufen.

echo $ conn-> errorCode (); echo $ conn-> errorInfo ();

Stattdessen ist es während der Entwicklung eine bessere Wahl, diese Einstellung auf zu aktualisieren PDO :: ERRMODE_EXCEPTION, was Ausnahmen auslösen wird, wenn sie auftreten. Auf diese Weise stoppen alle nicht erfassten Ausnahmen das Skript.

Als Referenz stehen folgende Optionen zur Verfügung:

  • PDO :: ERRMODE_SILENT
  • PDO :: ERRMODE_WARNING
  • PDO :: ERRMODE_EXCEPTION

Holen

Zu diesem Zeitpunkt haben wir eine Verbindung zur Datenbank hergestellt. Lass uns ein paar Informationen daraus holen. Es gibt zwei Möglichkeiten, um diese Aufgabe zu erfüllen: Abfrage und ausführen. Wir werden beide überprüfen.

Abfrage

/ * * Die Abfragemethode * Anti-Pattern * / $ name = 'Joe'; # Vom Benutzer eingegebene Daten try $ conn = new 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 als $ row) print_r ($ row);  catch (PDOException $ e) Echo 'ERROR:'. $ e-> getMessage (); 

Obwohl dies funktioniert, müssen Sie feststellen, dass wir die Daten des Benutzers immer noch manuell mit der Option "Escape" entfernen PDO :: Zitat Methode. Stellen Sie sich diese Methode als mehr oder weniger als PDO-Äquivalent vor mysql_real_escape_string; Es wird die Zeichenfolge entgehen, die Sie an es übergeben. Wenn Sie vom Benutzer bereitgestellte Daten an eine SQL-Abfrage binden, wird dringend empfohlen, stattdessen vorbereitete Anweisungen zu verwenden. Das heißt, wenn Ihre SQL-Abfragen nicht von Formulardaten abhängig sind, können Sie die Abfrage Die Methode ist eine hilfreiche Wahl und macht das Durchlaufen der Ergebnisse so einfach wie a für jeden Aussage.

Vorbereitete Anweisungen

/ * * Die Prepared Statements-Methode * Best Practice * / $ id = 5; try $ conn = new 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 'ERROR:'. $ e-> getMessage (); 

In diesem Beispiel verwenden wir die bereiten Methode, um die Abfrage buchstäblich vorzubereiten, bevor die Daten des Benutzers angehängt wurden. Mit dieser Technik ist die SQL-Injection praktisch unmöglich, da die Daten niemals in die SQL-Abfrage selbst eingefügt werden. Beachten Sie, dass wir stattdessen benannte Parameter verwenden (:Ich würde), um Platzhalter anzugeben.

Alternativ können Sie verwenden ? Die Parameter sind jedoch weniger lesbar. Halten Sie sich an die genannten Parameter.

Als Nächstes führen wir die Abfrage aus, während ein Array übergeben wird, das die Daten enthält, die an diese Platzhalter gebunden sein sollten.

$ stmt-> execute (array ('id' => $ id));

Ein alternativer, aber durchaus akzeptabler Ansatz wäre die Verwendung von bindParam Methode wie folgt:

$ stmt-> bindParam (': id', $ id, PDO :: PARAM_INT); $ stmt-> execute ();

Angabe des Ausgangs

Nach dem anrufen der ausführen Es gibt verschiedene Möglichkeiten, die Daten zu empfangen: ein Array (Standard), ein Objekt usw. Im obigen Beispiel wird die Standardantwort verwendet: PDO :: FETCH_ASSOC; Dies kann jedoch leicht überschrieben werden, falls erforderlich:

while ($ row = $ stmt-> fetch (PDO :: FETCH_OBJ)) print_r ($ row); 

Nun haben wir festgelegt, dass wir objektorientierter mit der Ergebnismenge interagieren möchten. Folgende Optionen stehen zur Verfügung:

  • PDO :: FETCH_ASSOC: Gibt ein Array zurück.
  • PDO :: FETCH_BOTH: Gibt ein Array zurück, das sowohl nach Spaltenname als auch nach 0 indiziert ist.
  • PDO :: FETCH_BOUND: Gibt TRUE zurück und ordnet die Werte der Spalten in Ihrer Ergebnismenge den PHP-Variablen zu, an die sie gebunden wurden.
  • PDO :: FETCH_CLASS: Gibt eine neue Instanz der angegebenen Klasse zurück.
  • PDO :: FETCH_OBJ: Gibt ein anonymes Objekt mit Eigenschaftennamen zurück, die den Spalten entsprechen.

Ein Problem mit dem obigen Code besteht darin, dass wir keine Rückmeldung geben, wenn keine Ergebnisse zurückgegeben werden. Lassen Sie uns das beheben:

$ stmt-> execute (array ('id' => $ id)); # Ein Array mit allen Ergebniszeilen erhalten $ result = $ stmt-> fetchAll (); # Wenn eine oder mehrere Zeilen zurückgegeben wurden… if (count ($ result)) foreach ($ result als $ row) print_r ($ row);  else echo "Keine Zeilen zurückgegeben."; 

Zu diesem Zeitpunkt sollte unser vollständiger Code so aussehen:

 $ id = 5; try $ conn = new 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 als $ row) print_r ($ row);  else echo "Keine Zeilen zurückgegeben.";  catch (PDOException $ e) Echo 'ERROR:'. $ e-> getMessage (); 

Mehrfachausführungen

Die PDO-Erweiterung wird besonders leistungsfähig, wenn dieselbe SQL-Abfrage mehrmals ausgeführt wird, jedoch mit unterschiedlichen Parametern.

try $ conn = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ conn-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); # Bereiten Sie die Abfrage vor ONCE $ stmt = $ conn-> prepare ('INSERT INTO SomeTable VALUES (: name)'); $ stmt-> bindParam (': name', $ name); # Erste Einfügung $ name = 'Keith'; $ stmt-> execute (); # Zweite Einfügung $ name = 'Steven'; $ stmt-> execute ();  catch (PDOException $ e) echo $ e-> getMessage (); 

Nachdem die Abfrage vorbereitet wurde, kann sie mehrmals mit verschiedenen Parametern ausgeführt werden. Der obige Code fügt zwei Zeilen in die Datenbank ein: eine mit dem Namen "Kevin" und die andere "Steven".


CRUD

Nachdem Sie nun den grundlegenden Prozess eingerichtet haben, lassen Sie uns schnell die verschiedenen CRUD-Aufgaben überprüfen. Wie Sie feststellen werden, ist der erforderliche Code für jeden Code praktisch identisch.

Erstellen (einfügen)

try $ pdo = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ pdo-> prepare ('INSERT TO TO SomeTable VALUES (: name)'); $ stmt-> execute (array (': name' => 'Justin Bieber')); # Betroffene Zeilen? echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) Echo 'Fehler:'. $ e-> getMessage ();

Aktualisieren

$ id = 5; $ name = "Joe the Plumber"; try $ pdo = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ stmt = $ pdo-> vorbereiten ('UPDATE someTable SET name =: name WHERE id =: id'); $ stmt-> execute (array (': id' => $ id, ': name' => $ name)); echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) Echo 'Fehler:'. $ e-> getMessage (); 

Löschen

$ id = 5; // Von einem Formular oder etwas Ähnlichem versuchen Sie $ 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); // Dieses Mal verwenden wir die bindParam-Methode $ stmt-> execute (); echo $ stmt-> rowCount (); // 1 catch (PDOException $ e) Echo 'Fehler:'. $ e-> getMessage (); 

Objektzuordnung

Einer der saubersten Aspekte von PDO (auch mysqli) ist, dass wir die Abfrageergebnisse einer Klasseninstanz oder einem Objekt zuordnen können. Hier ist ein Beispiel:

Klasse Benutzer public $ first_name; public $ last_name; öffentliche Funktion full_name () return $ this-> first_name. ". $ this-> last_name; try $ pdo = new PDO ('mysql: host = localhost; dbname = someDatabase', $ username, $ password); $ pdo-> setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION); $ result = $ pdo-> query ('SELECT * FROM someTable'); # Ergebnisse auf Objekt $ result-> setFetchMode (PDO :: FETCH_CLASS 'User'); while ($ user = $ result-> fetch ()) # Rufen Sie unsere benutzerdefinierte Methode full_name auf echo $ user-> full_name (); catch (PDOException $ e) echo 'Error:'. $ e-> getMessage ();

Schlussgedanken

Fazit: Wenn Sie das alte noch verwenden Mysql API für die Verbindung zu Ihren Datenbanken, stoppen Sie. Obwohl es noch nicht abgelehnt wurde, könnte es in Bezug auf Ausbildung und Dokumentation genauso gut sein. Ihr Code wird wesentlich sicherer und effizienter, wenn Sie die PDO-Erweiterung übernehmen. Überprüfen Sie die PDO-Elemente auf dem Envato Market, um zu sehen, was Sie tun können.