Einfacher Datenbankzugriff mit PDO

Seit PHP 5.1 ist ein Abstraktionsmodell für den Datenbankzugriff eingebaut. Seine Vorteile:

  • Es gibt ein einheitliches Verfahren für den Zugriff auf Datenbanken statt wie bisher unterschiedliche Funktionen für unterschiedliche Datenbanken
  • Zusatz-Features wie „Prepared Statements“ erleichtern die Verknüpfung von Daten und Variablen, sichern Zugriffe ab und beschleunigen Abfragen
  • Durch einen Umstieg auf PHP Database Objects, kurz PDO, werden Sie Datenbankzugriffe schneller und einfacher programmieren können.

Im folgenden Beispiel arbeiten Sie mit einer MySQL-Datenbank. Hier müssen Sie zunächst ein neues Datenbank-Objekt anlegen:

$strDbLocation = 'mysql:dbname=webdev;host=127.0.0.1';

$strDbUser = 'user';

$strDbPassword = 'pw';

try

{

  $objDb = new PDO($strDbLocation, $strDbUser, $strDbPassword);

}

catch (PDOException $e)

{

  echo 'Datenbank-Fehler: ' . $e->getMessage();

}

In den Variablen stehen die Zugangsdaten für den Server. Wichtig ist $strDbLocation, das den Typ der Datenbank beschreibt. In diesem Fall ist das mysql. Außerdem enthält die Variable Informationen darüber, welche Datenbank auf welchem Server geöffnet wird, hier webdev auf dem lokalen Rechner.

Das nachfolgende try…catch-Konstrukt fängt mögliche Fehler beim Öffnen der Datenbank ab und meldet diese. Klappt alles, bekommen Sie mit new PDO() eine neue Instanz des PHP Data Objects, das Sie über $objDb ansprechen.

Probieren Sie es gleich mit einem Schreibzugriff auf die MySQL-Datenbank. Als Beispiel dient eine simple Tabelle mit drei Feldern. Die erzeugen Sie in MySQL mit

CREATE TABLE `comment` (

  `id` bigint(20) unsigned NOT NULL auto_increment,

  `message` text NOT NULL,

  `email` text NOT NULL,

  PRIMARY KEY  (`id`)

)

Tragen Sie in die Tabelle comment eine kurze Botschaft und Ihre Mail-Adresse ein, zum Beispiel:

$intResult = $objDb->exec("INSERT INTO comment (message, email) VALUES ('Hallo Welt', 'ich@xy.de')");

echo $intResult;

Als Rückgabewert liefert pdo::exec die Anzahl der betroffenen Reihen, in diesem Beispiel eine 1. pdo::exec eignet sich, um Daten zu manipulieren. Für Select-Abfragen, die Daten zurück liefern sollen, ist dieses Verfahren aber nicht vorgesehen. Hier eignet sich pdo::query besser, wie das folgende Beispiel zeigt:

$dbResult = $objDb->query("SELECT * FROM daten");

Das Ergebnis $dbresult ist ein Array, auf dessen Einträge Sie bequem mit einer Schleife zugreifen, etwa:

foreach($dbResult as $row)

{

echo $row[0].“ „.$row[1].“<br/>\n“;

}

Prepared Statements sind „vorbereitete“ SQL-Abfragen. Einmal vorbereitet, lassen sich diese Statements mit Variablen verknüpfen. Ein Beispiel:

$dbInsertComment = $objDb->prepare("INSERT INTO comment (message, email) VALUES (:kommentar, :mailadresse)");

Als ersten Parameter geben Sie das SQL-Statement ein. Dieses Statement hat eine Besonderheit, die Sie in VALUES sehen. Hier stehen zwei Einträge mit vorangestellten Doppelpunkten. Das sind die Platzhalter für die späteren Daten. Die Zuordnung geschieht mit pdo::bindParam:

$dbInsertComment->bindParam('kommentar', $strKommentar);

$dbInsertComment->bindParam('mailadresse', $strMail);

Bei der Bindung wird nicht einmalig der Inhalt der Variablen übergeben, sondern ein Zeiger. Ändert sich der Variableninhalt, so gilt dieser Inhalt auch für das SQL-Statement.

Probieren Sie es aus:

$strKommentar = 'Hallo Mond';

$strMail = 'hubert@foo.bar';

$dbInsertComment->execute();

Die Methode excute() schreibt den aktuellen Inhalt der Variablen in die Datenbank. Danach wiederholen Sie den Vorgang mit anderen Werten:

$strKommentar = 'Das ist aber toll hier';

$strMail = 'schorsch@widget.com';

$dbInsertComment->execute();

Und damit stehen auch die neuen Daten in der Tabelle.

Wenn Sie Daten aus Arrays in die Datenbank schreiben wollen, sorgt ein Prepared-Statement für mehr Überblick im Code. Ein Beispiel:

$dbInsertComment = $objDb->prepare("INSERT INTO comment (message, email) VALUES (:kommentar, :mailadresse)");

$dbInsertComment->bindParam('kommentar', $strKommentar);

$dbInsertComment->bindParam('mailadresse', $strMail);

$arrComments = array(

array('comment' => 'Kommentar 1','mail' => 'hubsi@foo.bar'),

array('comment' => 'Kommentar "ich bin 2','mail' => 'max@xy.de'),

array('comment' => 'Kommentar 3','mail' => 'moritz@widget.com'),

);

foreach ($arrComments as $arrEntry)

{

  $strKommentar = $arrEntry['comment'];

  $strMail = $arrEntry['mail'];

  $dbInsertComment->execute();

}

Die Schleife geht durch das Array $arrComments, kopiert die jeweiligen Einträge in die Variablen und führt die Abfrage aus. Ganz nebenbei kümmert sich das Prepared Statement um die korrekte Aufbereitung der Daten, wenn wie in diesem Beispiel mitten im Eintrag ein Anführungszeichen steht. SQL-Injections verlieren damit ihren Schrecken, und Sie müssen die Daten nicht mehr extra aufbereiten, bevor Sie in die Datenbank kommen.

Und wenn es noch ein wenig kürzer sein soll, verzichten Sie auf die beiden bindParam-Zeilen und ersetzen Sie die foreach-Schleife mit

foreach ($arrComments as $arrEntry)

{

  $dbInsertComment->execute(

  array(

    'kommentar' => $arrEntry['comment'],

    'mailadresse' => $arrEntry['mail']

    )

  );

}

An pdo::execute können Sie nämlich ein assoziatives Array übergeben, das als Schlüssel die zuvor bestimmten Parameter und als Werte die zu schreibenden Daten enthält.

Prepared Statements in Abfragen

Mit Prepared Statements können Sie nicht nur in die Datenbank schreiben. Auch für Select-Abfragen lassen sich die Statements hervorragend nutzen. Ein Beispiel:

$dbFindComment = $objDb->prepare("SELECT * FROM comment WHERE message LIKE :search");

Hier bereiten Sie alles für eine simple Textsuche in comment vor. Danach binden Sie wie gehabt den Suchparameter an eine Variable:

$dbFindComment->bindParam('search', $strSuche);

Anschließend belegen Sie die Variable, hier etwa mit

$strSuche = '%hallo%';

Die Prozentzeichen stehen bei LIKE-Bedingungen in SQL-Abfragen für beliebigen Text. Diese Suche findet also alle Einträge, in denen die Zeichenkette „hallo“ vorkommt.

Mit

$dbFindComment->execute();

schicken Sie die Suchanfrage ab. Das Ergebnis lesen Sie aus, indem Sie sich durch das Query-Objekt selbst hangeln wie durch ein Array:

foreach($dbFindComment as $row)

{

  echo $row[0]." ".$row[1]."<br/>\n";

}

Auch hier sehen Sie wieder eine Liste aller gefundenen Beiträge.

Das Experimentieren mit PDO lohnt sich: Sie sparen viel Arbeit mit Prepared Statements, ein späterer Umstieg auf andere Datenbanken wird leichter dank einheitlicher Funktionsaufrufe und schließlich wird alles noch ein wenig bequemer. Warum also nicht PDO einsetzen?

Ähnliche Beiträge

3 Gedanken zu “Einfacher Datenbankzugriff mit PDO

  1. Hm, ich finde die Darstellung des Codes eher weniger gelungen, weswegen ich eigentlich auch relativ schnell keiner Lust mehr hatte den Beitrag zu lesen.

  2. hmmm, nett geschrieben. Aber ich bin so gewöhnt an die klassische Arbeitsweise mit Mysql und tue mich schwer wieder alles umzustellen und neu zu lernen. Ich würde mir eine Seite wünschen, die die bisherige Vorgehensweise mit Insert und Update und select und mysql_fetch_assoc usw. mal direkt den neuen Möglichkeiten gegenüberstellt um eventuelle Vorteile zu zeigen.

  3. Danke, für ein paar praktische Beispiele die funktionieren, werde meinen Code auf PDO umstellen. In nachfolgendem Zitat stimmen die Anführungszeichen nicht: echo $row[0].“ „.$row[1].“n“;

Kommentare sind geschlossen.