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.

revilodesign oli

3 Kommentare

Schreibe ein Kommentar zu Datenbankabfragen in WordPress mit wpdb

  1. avatar christianChristian sagt:

    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

    • avatar adminadmin sagt:

      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

  2. avatar defsanderDefSander sagt:

    .. 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

Hinterlasse ein Kommentar zum Beitrag "Datenbankabfragen in WordPress mit wpdb"

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Letzte Aktualisierung am 29.04.2024 / Affiliate Links / Bilder von der Amazon Product Advertising API

Follow Me

doch mal auf Instagram