Datenbankarbeit in Drupal 7 – Lektion 3 – Statische Abfragen (SELECT)
Die allgemeinste Form einer Abfrage in Drupal ist die statische Abfrage. Eine statische Abfrage wird wortwörtlich an die Datenbank übergeben. Nur SELECT-Abfragen können statisch sein.
Statische Abfragen sollten nur bei sehr einfachen Anfragen verwendet werden. Für komplexe, dynamisch erstellte oder zur Laufzeit modifizierte Abfragen sollten Sie dynamische Abfragen verwenden.
Ein einfacher Weg, eine statische Abfrage durchzuführen, ist über die Query-Methode:
<?php $result = $conn->query("SELECT nid, title FROM {node}"); ?>
Die prozedurale Hülle ist vorzuziehen:
<?php $result = db_query("SELECT nid, title FROM {node}"); ?>
Der Aufruf von db_query() wie oben ist äquivalent zu:
<?php $result = Database::getConnection()->query("SELECT nid, title FROM {node}"); ?>
Schauen wir uns an, warum die Verwendung von db_query die bessere Wahl ist, als direkt auf das Database-Objekt zuzugreifen.
db_query() nimmt drei Argumente entgegen. Das erste ist der Query-String mit Platzhaltern, wo nötig, und alle Tabellennamen in geschweiften Klammern. Das zweite ist ein Array mit Platzhalter-Werten. Das dritte, optional, ist ein Array mit Konfigurationsparametern, wie die Abfrage ausgeführt werden soll.
Präfix
In statischen Abfragen müssen alle Tabellen in {} eingeschlossen sein. Dies ermöglicht es, Präfixe für Tabellennamen hinzuzufügen. Präfixe erlauben es, mehrere Seiten in einer einzigen Datenbank zu betreiben, indem für die Tabellen unterschiedliche Präfixe genutzt werden, z. B. "site1_", "site2_".
Platzhalter
Platzhalter markieren Stellen, an denen Werte eingesetzt werden sollen. Durch die Trennung von Platzhaltern und SQL-Syntax erlaubt die Datenbank, den SQL-Code von Benutzerwerten zu trennen, um SQL-Injektionen zu verhindern.
<?php $result = db_query("SELECT nid, title FROM {node} WHERE created > :created", array( ':created' => REQUEST_TIME - 3600, )); ?>
Der obige Code wählt alle Nodes aus, die vor weniger als einer Stunde erstellt wurden. Der Platzhalter :created wird dynamisch durch REQUEST_TIME - 3600 ersetzt, wobei REQUEST_TIME der Zeitpunkt der Ausführung ist. Eine Abfrage kann beliebig viele Platzhalter haben, aber jeder muss einen eindeutigen Namen haben, auch wenn Werte identisch sind.
Je nach Anwendung kann das Array mit Platzhaltern inline (wie im obigen Beispiel) oder vorher definiert und später übergeben werden. Die Reihenfolge im Array spielt keine Rolle. Platzhalter, die mit "db_" beginnen, sind vom System reserviert und sollten nicht explizit verwendet werden.
Beachten Sie, dass Platzhalter je nach Typ mit oder ohne Anführungszeichen verwendet werden sollten. Beispielsweise müssen Zeichenkettenwerte nicht in Anführungszeichen eingeschlossen werden, da das Datenbanksystem das übernimmt, numerische Werte aber nicht.
<?php // FALSCH: $result = db_query("SELECT nid, title FROM {node} WHERE type = ':type'", array( ':type' => 'page', )); // RICHTIG: $result = db_query("SELECT nid, title FROM {node} WHERE type = :type", array( ':type' => 'page', )); ?>
Platzhalter sollten nicht für Tabellennamen oder Spalten verwendet werden, sie dienen nur zum Einsetzen von Zeichenketten- oder Zahlenwerten.
Array-Platzhalter
Die Datenbankschicht von Drupal bietet eine besondere Funktion für Platzhalter. Wenn Werte als Array übergeben werden, werden sie automatisch in eine durch Kommas getrennte Liste umgewandelt. So müssen Entwickler nicht mehr zählen, wie viele Platzhalter sie benötigen. Beispiel:
<?php db_query("SELECT * FROM {node} WHERE nid IN (:nids)", array(':nids' => array(13, 42, 144))); // Entspricht: db_query("SELECT * FROM {node} WHERE nid IN (:nids_1, :nids_2, :nids_3)", array( ':nids_1' => 13, ':nids_2' => 42, ':nids_3' => 144, )); // Also äquivalent zu folgender Abfrage: db_query("SELECT * FROM {node} WHERE nid IN (13, 42, 144)"); ?>
Abfrageparameter
Der dritte Parameter von db_query() ist ein Array mit Optionen, die steuern, wie die Abfrage ausgeführt wird. Üblicherweise werden nur zwei Optionen genutzt, andere sind für den internen Gebrauch bestimmt.
Der Schlüssel "target" definiert, für welchen Zweck die Abfrage gedacht ist. Wenn er nicht gesetzt ist, wird "default" verwendet. Zurzeit zeigt nur "slave" an, dass die Abfrage auf einem Slave-Server ausgeführt werden soll, falls vorhanden. Der Schlüssel "fetch" bestimmt, wie die Ergebnisse von der Datenbank zurückgegeben werden. Mögliche Werte sind: PDO::FETCH_OBJ, PDO::FETCH_ASSOC, PDO::FETCH_NUM, PDO::FETCH_BOTH oder ein Klassenname als String. Ist ein Klassenname angegeben, wird jede Zeile als neues Objekt dieser Klasse zurückgegeben.
Das Verhalten aller Werte folgt der PDO-Spezifikation: Ergebnisse können als stdClass-Objekte, assoziative Arrays, numerische Arrays oder gemischte Arrays zurückgegeben werden.
- PDO::FETCH_OBJ – Objekt.
- PDO::FETCH_ASSOC – assoziatives Array.
- PDO::FETCH_NUM – numerisches Array.
- PDO::FETCH_BOTH – Array mit beiden Schlüsseln (numerisch und assoziativ).
Siehe http://php.net/manual/en/pdostatement.fetch.php. Standard ist PDO::FETCH_OBJ, was Sie verwenden können, wenn Sie keine besonderen Anforderungen haben.
Im folgenden Beispiel wird die Abfrage auf dem Slave-Server ausgeführt (wenn verfügbar) und die Ergebnisse als assoziatives Array zurückgegeben:
<?php $result = db_query("SELECT nid, title FROM {node}", array(), array( 'target' => 'slave', 'fetch' => PDO::FETCH_ASSOC, )); ?>