Datenbankabfragen in WordPress mit wpdb
Gerade für Leute die eigene Plugins oder eine eigene einfache Funktion schreiben möchten ist eine Datenbankabfrage in WordPress unabdingbar. Daher behelfen wir uns der Klasse wpdb, die uns WordPress zur Verfügung stellt. Mit dieser kann man beispielsweise Datenbanksätze aktualisieren (Update), neue Datensätze hinzufügen (INSERT) oder einfach nur Daten auslesen (SELECT).
Ich möchte Euch in diesem Blog-Beitrag zeigen, wie Ihr mit dem wpdb-Objekt eine Datenbankabfrage in WordPress macht.
Wenn Ihr mit der Klasse wpdb arbeiten wollt, dann müsst Ihr sie zunächst einmal initialisieren. Das geschieht mit der globalen Variable $wpdb
:
Keine Produkte gefunden.
Wie funktioniert die Datenbankabfrage mit wpdb?
Wer sich ein wenig in Programmieren auskennt, der weiß, dass es schon zahlreiche PHP Klassen gibt. Wieso also wpdb? wpdb liefert zusätzlich einige Informationen, die für die Datenbankverbindung hilfreich sein könnten. So müsst Ihr beispielsweise bei einem Umzug eurer Webseite nur die wp-config.php anpassen und nicht den Code.
Beginnen wir mit den wpdb Basics
function meinPlugin() {
global $wpdb;
}
Beispieltabelle wp_posts
Im folgenden Versuche ich euch ein paar Beispiele anhand der folgenden Tabelle zu verdeutlichen.
ID | post_title | post_category | post_status | post_type |
---|---|---|---|---|
1 | BMW | Auto | publish | post |
2 | Audi | Auto | publish | post |
3 | Mercedes | Auto | publish | post |
4 | Opel | Auto | publish | post |
5 | Porsche | Auto | publish | post |
6 | Kawasaki | Motorrad | publish | post |
7 | Autos | Auto | publish | page |
8 | Motorräder | Motorrad | publish | page |
9 | Ruderboot | Boote | draft | page |
10 | BMW | Motorrad | publish | post |
Die Unterschiedlichen Rückgabewerte von wpdb
Ich habe am Anfang selbst einige Zeit benötigt um herauszufinden, welche Abfragen welche Werte zurückgeben. Dabei habe ich für mich festgestellt, dass ich am liebsten mit get_results arbeite, welches mir ein array zurückgibt. Der besseren Übersicht halber hier die möglichen Variablen von wpdb:
Tipp: Variablennamen anklicken und Ihr springt zum entsprechenden Bereich im Beritrag
- $wpdb->prefix
$wpdb->prefix
gibt den Prefix deiner WordPress Datenbank wieder. - $wpdb->get_row
Mit$wpdb->get_row
könnt Ihr eine einzelne Zeile abrufen. Gibt es mehrere Werte wird get_row euch nur den ersten ausgeben. - $wpdb->get_results
Möchtet Ihr mehrere Werte aus der Datenbank von WordPress auslesen, dann solltet Ihr mit$wpdb->get_results
arbeiten. - $wpdb->num_rows
num_rows gibt nur die Anzahl der gefundenen Treffer zurück. Muss aber unmittelbar nach dem Abruf der Variable aufgerufen werden. - $wpdb->show_errors()
Zeigt Fehler in der Abfrage an. - $wpdb->print_error()
Zeigt Fehler in der SQL Anweisung an.
Im folgenden möchte ich Euch anhand der möglichen Variablen zeigen, wie Ihr die Daten auf den unterschiedlichen Arten erhaltet und auslesen könnt.
$wpdb->prefix
Bei jeder Installation fragt Euch WordPress welchen Tabellen Prefix Ihr verwenden möchte. Standardmäßig schlägt WordPress „wp_“ vor. Es gibt aber unterschiedliche Gründe diesen zu ändern: Zum einen erschwert man es somit Hackern schnell die Tabellen zu finden. Zum anderen macht es Sinn den Prefix zu ändern, wenn man beispielsweise einen Blog und ein Shopsystem in der selben WordPress Datenbank speichert. Aus der „wp_config.php“ holt sich $wpdb->prefix
den Tabellen Prefix. Daher verwende ich anstelle von „wp_posts“ die Variable „.$wpdb->prefix.“posts.
Beispiel $wpdb->prefix
: Ändere ich den Prefix von „wp_“ in „new_“ muss ich nur eine Stelle ändern – und zwar in der „wp_config.php“ und nicht meinen kompletten Code durchgehen, denn „.$wpdb->prefix."posts
gibt mir „new_posts“ aus.
$wpdb->get_row
Wenn man also nur eine einzelne Zeile als Rückgabewert haben möchte, dann verwendet man $wpdb->get_row
. In meinem folgenden Beispiel möchte ich beispielsweise alle Daten aus der Tabelle wp_post mit der ID = 1 und kann den post_title BMW ausgeben lassen.
function meinPlugin() {
global $wpdb;
$vehicle = $wpdb-> get_row("SELECT * FROM ".$wpdb->prefix."posts WHERE ID = 1");
echo $vehicle->post_title; // BMW
}
$wpdb->get_results
Mit $wpdb->get_results
können mehrere Ergebnisse aus der WordPress Datenbank ausgelesen werden.
Im folgenden Beispiel möchte ich zum Beispiel alle Marken auslesen, die in der Kategorie „Autos“ gespeichert wurden.
function meinPlugin() {
global $wpdb;
$vehicles = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."posts WHERE post_category LIKE 'Auto'");
foreach ( $vehicles as $vehicle ) {
echo 'Marke: ' . $vehicle->post_title;
}
}
/*
AUSGABE:
Marke: BMW
Marke: Audi
Marke: Mercedes
Marke: Opel
Marke: Porsche
Marke: Autos
*/
Standardmäßig liefert $wpdb->get_results
ein Array zurück. Daher nutze ich die foreach, um alle Daten als string auszugeben. Man könnte natürlich alle Werte auch als return wieder geben und diese dann später im Template verarbeiten. Zudem könnte man den SELECT auch noch anpassen und nur Marken ausgeben, die den „post_type“ post haben, aber es soll Euch ja auch nur als Beispiel dienen.
$wpdb->num_rows
Eine nützliche Funktion, wenn man nur die Anzahl der Treffer auslesen möchte, ist die Variable $wpdb->num_rows
. Um dies zu veranschaulichen nutze ich das eben verwendete Beispiel.
function meinPlugin() {
global $wpdb;
$vehicles = $wpdb-> get_results("SELECT * FROM ".$wpdb->prefix."posts WHERE post_category LIKE 'Auto'");
$vehicles_count = $wpdb->num_rows;
echo 'Treffer: ' . $vehicles_count;
/*
Treffer: 6
*/
}
Im vorigen Beispiel habe ich die Markennamen ausgegeben. Aber in diesem Beispiel gibt $wpdb->num_rows
die Anzahl der Treffer wieder und das ist in diesem Beispiel 6.
Die Rückgabewerte
Es gibt 3 mögliche Rückgabewerte, die $wpdb->get_row
und $wpdb->get_results
liefern.
Daten gefunden
Man erhält ein gefülltes Array.
Array (
[0] => stdClass Object ( [post_title] => BMW, [post_category] => Auto )
[1] => stdClass Object ( [post_title] => Audi, [post_category] => Auto )
[2] => stdClass Object ( [post_title] => Mercedes, [post_category] => Auto )
)
Keine Daten gefunden
Gibt ein leeres Array wieder.
Array ()
Fehler
Fehler bei der WordPress Datenbankabfrage mit wpdb.
NULL
Wenn wir also definitiv einen Rückgabewert aus unserer Funktion haben möchten können wir Sie wie folgt umschreiben:
function meinPlugin() {
global $wpdb;
$vehicles = $wpdb->get_results("SELECT * FROM ".$wpdb->prefix."posts WHERE post_category LIKE 'Auto'");
if( $vehicles !== NULL ) { // KEIN FEHLER
if( !empty( $vehicles ) ) { // DATEN WURDEN GEFUNDEN
foreach ( $vehicles as $vehicle ) {
echo 'Marke: ' . $vehicle->post_title;
}
} else { // KEINE DATEN WURDEN GEFUNDEN
echo 'Keine Treffer gefunden!';
}
} else { // WENN FEHLER
echo 'Fehler';
}
}
Mit den Abfragen der Rückgabewerte von wpdb seid Ihr auf jeden Fall auf der sicheren Seite und werdet definitiv Daten erhalten – im besten Falle natürlich die, die Ihr auch wollt 🙂
Fehlersuche bzw. Debugging
Ich glaube jeder kennt es – man weiß einfach nicht wo der Fehler vergraben liegt. Aber zum Glück gibt es mit $wpdb->show_errors()
und $wpdb->print_error()
zwei nützliche Helferlein im Kampf gegen die eigene Dummheit.
Vorab: Die Variable „Debugging“ muss in der Datei „wp_config.php“ auf true stehen!
$wpdb->show_errors()
Mit $wpdb->show_errors()
kann man ganz gut falsch geschriebene Spaltennamen herausfinden. Wichtig ist zu wissen, dass $wpdb->show_errors()
vor der Abfrage ausgeführt werden muss.
$wpdb->print_error()
Neben den Fehlern in der Abfrage kann es aber auch dazu kommen, dass sich Fehler in die SQL Anweisung geschlichen haben. Diese kann man mit $wpdb->print_error()
sehr gut herausfinden. Diese muss aber unbedingt direkt nach der Abfrage ausgeführt werden. $wpdb->print_error()
zeigt dann die vorherige SQL-Abfrage an und man kann relativ schnell sehen, wo der Fehler liegt.
Hinweis: Nach dem erfolgreichen Debuggen die Zeilen wieder aus den Code nehmen!
Abfragen vor SQL-Injection schützen
Eine der häufigsten Schwachstellen und ein gefundenes Fressen für Hacker sind Daten, die ungeschützt und ungeprüft übergeben und weiterverarbeitet werden. Dabei ist es so einfach seine Werte zu sichern. WordPress gibt uns sogar mit esc_sql()
eine einfache aber sichere Funktion zu Hand, die wir unbedingt nutzen sollten!
function meinPlugin( $category ) {
global $wpdb;
$category_name = esc_sql( $category );
$vehicles = $wpdb-> get_results("SELECT * FROM ".$wpdb->prefix."posts WHERE post_category LIKE '" . $category_name . "'");
$vehicles_count = $wpdb->num_rows;
echo 'Treffer: ' . $vehicles_count;
}
Im Beispiel oben übergebe ich der Funktion meinPlugin den Kategorienamen. Dieser kann mittels $_POST
oder $_GET
übergeben worden sein und somit ein leichtes „Opfer“ für einen Hacker-Angriff. Also Fange ich $category
ab und Escape die Variable und übergebe es einer neuen Variablen, mit der ich nun sicher weiterarbeiten kann.
Danke für den Beitrag. Hat mir geholfen. Ein kleiner Fehler hat sich meiner Meinung nach im Artikel eingeschlichen. Es wird die Funktion ‚is_empty(…)‘ aufgerufen. Diese gibt es in PHP allerdings nicht. Vermutlich meinten Sie in diesem Kontext die Funktion ‚empty(…)‘.
Gruße Christian
Hi Christian,
vielen Dank für dein Kommentar. Natürlich gibt es nicht is_empty – Sorry. Habe ich sofort behoben … Besser wäre sogar die isset() Abfrage 🙂 Vielen Dank für den Hinweis.
Lg Oli
.. hi Oli,
2 Fragen:
1. wenn die Abfrage über die WPDB „usr_webnnn…“, dort auf z.B. auf wp_530posts und Einträge finde – wo und wie kann ich diese auf auf Website / Webseite darstellen?
2. ich habe ein numerische (varchar) imKontaktformular eingerichtet – wie kann ich den numerischen Inhalt ändern?
Danke
Def