Mit wpdb Daten aus der WordPress-Datenbank lesen (SELECT)

Von | 9. Juni 2016

wordpress wpdb SELECTWenn man eigene Plugins in WordPress erstellen möchte, ist die Funktion, bzw. Klasse wpdb überlebenswichtig. Mit dieser könnt ihr mit eurer Datenbank kommunizieren und genau das machen, was benötigt wird. Das heißt ihr könnt Daten eintragen (Insert), updaten (Update), abrufen (Select) und noch viel mehr.

Natürlich könnt ihr auch einfach die WordPress-Dokumentation lesen, die im Falle des wpdb-Objekts ziemlich gut ist. Aber ich denke ich kann noch ein paar Beispiele beisteuern, die den ein oder anderen Denkfehler verhindert. Diese haben mir extrem viel Zeit gekostet.

In diesem Blogbeitrag konzentriere ich mich jedoch vor allem auf das Abfragen von Daten.

Wieso wpdb?

Programmierer, die zum ersten Mal ein WordPress-Plugin programmieren, werden sich wohl fragen, wieso man dafür überhaupt eine eigene Funktion benötigt. Schließlich gibt es in PHP schon eine eigene Klasse dafür.

wpdb liefert allerdings noch die ein oder andere nützliche Funktion mit, die ihr in eurem Plugin gebrauchen könnt. Außerdem kümmert sie sich um die Verbindung zur Datenbank. Das heißt, wenn ihr beispielsweise eure WordPress Seite umzieht, dann müsst ihr nur die wp_config.php Datei anpassen, aber nicht euren Code. Und Wartungseffizienz sollte das Ziel jedes Programmierers sein.

Grundeinstellung und Beispielszenario

Zuallererst dürft ihr nie vergessen, die Klasse zu initialisieren. Das geschieht mit der globalen Variable $wpdb:

function test()
{
  global $wpdb; //Wenn du in dieser Funktion mit deiner Datenbank kommunizieren möchtest, musst du die globale Klasse wpdb initialisieren. 
}

Um meine Beispiele anschaulicher zu gestalten werde ich mich von folgender “Datenbanktabelle” bedienen.

wp_mannschaften

IDnamesportartgruendungsjahr
1SSV Jahn RegensburgFußball1889
2FC Bayern MünchenFußball1900
3Stuttgarter KickersFußball1899
4Dallas MavericksBasketball1967
5Denver BroncosFootball1960
6Pittsburgh SteelersFootball1933

Abfragen mit wpdb

Es gibt mehrere Möglichkeiten, Abfragen mit wpdb durchzuführen. Ich werde lediglich auf die Möglichkeit einen, bzw. mehrere Datensätze abzufragen eingehen. Es ist mit “get_var” zwar noch möglich eine einzelne Variable abzufragen, allerdings habe ich das noch nie gebraucht, sehe auch keine große Notwendigkeit dafür.

SELECT ROW mit $wpdb->get_row

Mit $wpdb->get_row(“Abfragestring”) könnt ihr eine einzelne Zeile abrufen. Gibt es mehrere Ergebnisse zu eurem SQL-Befehl, spuckt die Funktion den ersten Eintrag, den eure Datenbank findet aus.

Möchte ich also alle Informationen zum SSV Jahn Regensburg haben, sieht meine Abfrage folgendermaßen aus:

function get_infos()
{
  global $wpdb;
 
  $mannschaftsinfos = $wpdb->get_row("SELECT * FROM ".$wpdb->prefix."mannschaften WHERE ID = 1"); 
 
  echo "Vereinsname: ".$mannschaftsinfos->name; //SSV Jahn Regensburg  
}

Die Informationen sind also in einem Objekt gespeichert. Die Klasse erlaubt auch noch eine Ausgabe als assoziatives und numerisches Array. Aber da ich bisher keine Anwendungsfälle dafür gefunden habe, lasse ich das einfachheitshalber weg.

$wpdb->prefix

Für alle, die sich wundern warum nach dem FROM nicht wp_mannschaften sondern “.$wpdb->prefix.”mannschaften steht, ist hier schon die erste Lektion, die ich nach tausenden Zeilen Code schmerzhaft lernen durfte. Der Präfix einer Datenbanktabelle sollte sich natürlich zufällig zusammensetzen um es beispielsweise Hackern bei einem Angriff auf eure Datenbank schwerer zu machen.

Manchmal haben Präfixe allerdings auch praktischen Wert, wenn du zum Beispiel die gleiche Datenbanktabelle öfters verwenden möchtest. Ein Anwendungsbeispiel ist mein Browsergame. Damit ich einzelne “Welten” sauber abschließen kann und die Performance erhöhe, hat jede Tabelle die zu einer Welt gehört ihren eigenen Präfix. Die Tabellen heißen dann bspsw.: welt1_mitspieler, welt2_mitspieler, welt3_mitspieler, welt1_clans, welt2_clans, welt3_clans usw…

Zurück zum WordPress Plugin. Ich dachte dummerweise, WordPress Tabellen haben generell den Präfix “wp_” was freilich nicht stimmt. Jedes WordPress Projekt sollte unbedingt einen zufälligen anderen Tabellenpräfix besitzen. Diesen kann und muss man auch in der “wp_config.php” Datei konfigurieren. Dort holt sich auch die Klasse wpdb den Präfix.

SELECT RESULTS mit $wpdb->get_results

Mit dem Befehl $wpdb->get_results(“SQL String”); können mehrere Ergebnisse aus der Datenbank ausgelesen werden.

Möchte ich zum Beispiel den Namen und das Gründungsjahr aller Mannschaften, die nach 1901 gegründet worden sind ausgeben lassen, gehe ich folgendermaßen vor:

function get_mannschaften()
{
  global $wpdb;     
 
  $mannschaftsinfos = $wpdb->get_results("SELECT name, gruendungsjahr FROM ".$wpdb->prefix."mannschaften WHERE gruendungsjahr > 1901"); 
  $gefundene_mannschaften = $wpdb->num_rows;
  foreach($mannschaftsinfos as $mannschaft)
  {
    echo "Vereinsname: ".$mannschaft->name;
    echo " | Gründungsjahr: ".$mannschaft->gruendungsjahr."<\br>";
  }
  echo "Gefundene Mannschaften: ".$gefundene_mannschaften;
}  
  /*
  Vereinsname: Dallas Mavericks | Gründungsjahr: 1967
  Vereinsname: Denver Broncos | Gründungsjahr: 1960
  Vereinsname: Pittsburgh Steelers| Gründungsjahr: 1933 
  Gefundene Mannschaften: 3
  */

Die foreach Schleife ist nötig, da die Funktion standardmäßig ein Array zurückliefert, in denen die Objekte gespeichert sind. Theoretisch könnte man natürlich auch das Array selbst durchgehen. Möchte man den Vereinsnamen des ersten Eintrags zurückgeben könnte man auch $mannschaftsinfos[0]->name verwenden.

Eine kleine Erleichterung ist auch die Funktion $wpdb->num_rows, welches die Anzahl der Ergebnisse zurückgibt. Diese muss aber unmittelbar nach der Abfrage aufgerufen werden. Sie erweist sich als hilfreich, wenn man doch eine “normale” FOR-Schleife verwenden möchte.

Select Rückgabewerte

Was mir zu Beginn auch viele Nerven gekostet hat war, dass ich die Rückgabewerte missinterpretiert habe. $wpdb->get_row und $wpdb->get_results liefern folgende Werte zurück (mit obigen Beispiel):

Bei Erfolg: 

  Array ( [0] => stdClass Object ( [name] => Dallas Mavericks  [gruendungsjahr] => 1967 ) 
          [1] => stdClass Object ( [name] => Denver Broncos [gruendungsjahr] => 1960 ) 
          [2] => stdClass Object ( [name] => Pittsburgh Steelers [gruendungsjahr] => 1933 )
        )

Keine Werte gefunden:

  Array ( )

Bei Fehlern:

NULL

In unserem Beispiel möchte man vielleicht wissen, ob es ein Verein gibt, der vor 1800 gegründet wurde:

function get_mannschaften()
{
  global $wpdb;
 
  $mannschaftsinfos = $wpdb->get_results("SELECT name, gruendungsjahr FROM ".$wpdb->prefix."mannschaften WHERE gruendungsjahr < 1800"); 
 
  if($mannschaftsinfos !== NULL) //Wenn nicht Null
  {
    if(!is_empty($mannschaftsinfos)) //Wenn Array nicht leer
    {
      foreach($mannschaftsinfos as $mannschaft) // Gebe Mannschaften aus
      {
        echo "Vereinsname: ".$mannschaft->name;
        echo " | Gründungsjahr: ".$mannschaft->gruendungsjahr."<\br>";
      }
    } else {
      echo "Zu dieser Abfrage wurden keine Ergebnisse gefunden"; //Keine Ergebnisse
    }
  } else {
    echo "Abfragefehler"; //Fehler
  }
}

Dann liefert die Abfrage ein leeres Array zurück, was zur Ausgabe “Zu dieser Abfrage wurden keine Ergebnisse gefunden” führen würde. Bei kritischen Transaktionen, kann man mit “=== NULL” auf einen Fehler in der Abfrage prüfen und ein entsprechendes Error Handling einbauen.

Ich würde mich freuen, wenn du meinen Newsletter abonnieren würdest. Dann verpasst du auch keinen interessanten Beitrag mehr.

Benachrichtige mich:
Datenschutzbestimmungen *
Mein Newsletter informiert dich über Themen der Selbständigkeit, Bloggen, Marketing und Programmierung. Kann Werbung enthalten. Informationen zum Anmeldeverfahren, Versanddienstleister, statistischer Auswertung und Widerruf findest du in meinen Datenschutzbestimmungen


Abfragen vor SQL-Injection schützen

Ganz peinlich wird es, wenn dein Plugin durch so etwas simples wie eine SQL-Injection geknackt wird. Also solltest du dir Ärger sparen, indem du deine Abfragen sicher gestaltest. Die WordPress-Dokumentation schlägt unter anderem vor, die Abfragen zuerst zu preparen. Das kann man machen, halte ich persönlich für zu unübersichtlich, weshalb ich die Escape-Funktionen von WordPress nutze, bevor ich eine Variable in einer Abfrage verwende.

Hier ist exemplarisch eine Funktion, die eine Mannschaftsabfrage nach der übergebenen ID ausführen soll. Die Funktion kann von überall aufgerufen werden und womöglich einen Wert aus einer POST oder GET-Variable enthalten. Das wäre ein gefundenes Fressen für Hacker. Deshalb solltet ihr so vorgehen:

function get_infos($mannschaft_id)
{
  global $wpdb;
 
  $mannschaft_id = esc_sql($mannschaft_id); //Escaped den übergebenen Wert
 
  $mannschaftsinfos = $wpdb->get_row("SELECT * FROM ".$wpdb->prefix."mannschaften WHERE ID = '$mannschaft_id'"); 
 
  return $mannschaftsinfos;
}

Die Escape-Funktion gibt es noch für mehrere Anwendungsbeispiele wie die Textarea oder für URLs. Eine Liste und die Erklärungen findet ihr am Ende dieser Doku.

Debugging

Es gibt zwei sehr nützliche Befehle, die einem beim Debuggen bei der Verwendung von wpdb sehr behilflich sind. Dafür muss aber die Variable “Debugging” in der Datei “wp_config.php” auf true stehen.

Mein häufigster Fehler, warum meine Abfragen nicht funktionieren sind falsch geschriebene Spaltennamen. Diese kann ganz gut mit dem Befehl

$wpdb->show_errors();

debuggen. Diesen musst du vor der Abfrage ausführen. Show Errors zeigt alle Fehler in der Abfrage an.

Was bei komplexeren Abfragen oft vorkommt ist, dass man einfach einen kompletten Nonsens in seine SQL Anweisung geschrieben hat, die Syntax aber keine Fehler enthält. Man sieht es aber nicht im Code, weil alles durch Variablen und übergebenen Werten unübersichtlich ist. Dann hilft mir immer:

$wpdb->print_error();

weiter. Diesen Befehl musst du allerdings unbedingt direkt nach der Abfrage ausführen. Print Error zeigt die vorherige SQL-Abfrage noch einmal im Klartext an. Egal ob bei Erfolg oder Misserfolg. So kann man relativ schnell sehen, ob man einen Scheiß zusammenprogrammiert hat.

Aber bitte vergesst nicht, die Befehle wieder aus dem Code zu nehmen oder sie zumindest auszukommentieren, wenn ihr fertig mit Debuggen seid.

Ich hoffe, ich konnte euch mit diesem Artikel die SELECT Abfragen mit wpdb ein wenig näherbringen.

Robert von Plötzlich-Selbständig.de Schwarz/Weiß Bild

Ich freue mich von dir zu hören!

Du kommst bei deinem Projekt nicht weiter oder brauchst einen Boost? Dann lass dir von mir helfen zum Beispiel bei:

► Beratung für Selbständige, Gründer & Ideenschmiede
Egal, ob du erste Tipps brauchst. Einmal über deine Idee reden möchtest oder mit mir das Konzept für das nächste Facebook ausarbeiten willst.

► Entwicklung von Software, APPs & Webseiten
Beispielsweise: WordPress Shops & Plugins, (Gaming-)Apps, Datenbank-Applikationen oder andere smoothe Anwendungen!

Mehr Infos, Preise und Kontaktmöglichkeiten findest du hier!

11 Gedanken zu „Mit wpdb Daten aus der WordPress-Datenbank lesen (SELECT)

  1. Hildebrandt

    Super Anleitung.
    Bin selbst PHP Programmierer und will meine WordPresseite mit Daten aus einer eigenen Dtenbank bestücken und ausgeben.
    Wie bekomme ich es hin, das mir die Daten nicht oberhalb der Design-DIV Kontainer angezeigt werden?
    Kann nix darüber finden. Haben Sie einen Tip bzw. Literatur?
    Viele Grüße

    Antworten
    1. Robert Beitragsautor

      Das liegt vermutlich daran, dass du es tatsächlich auch dort ausgibst.

      Am Besten ist, du bastelst ein kleines Plugin und machst aus der Ausgabe ein Shortcode. Und diesen Shortcode baust du dann dort ein, wo du möchtest.
      https://codex.wordpress.org/Shortcode_API
      Oder rufst halt die Funktion dort auf, wo es ausgegeben werden soll. Das heißt du suchst den DIV-Container in deinem Design und rufst dort die Funktion auf.

      Wollte dazu auch noch was machen, aber das wird noch dauern, bis ich dazu komme :-/

      Antworten
      1. Heinz W.

        Hallo und Guten Morgen,

        ich habe das selbe Thema. Der gleiche Code in drei unterschiedlichen Installationen (Themes) ergibt zweimal die richtige Ausgabe und einmal erscheint die Ausgabe direkt im Contentbereich und zusätzlich direkt unter dem -Tag, also doppelt.

        > Das liegt vermutlich daran, dass du es tatsächlich auch dort ausgibst.
        Nein, die Ausgabe ist da nicht vorgesehen und wird auch nur einmal eingebaut.

        Ich habe schon Stunden damit verbracht zu suchen, warum der Code unter BODY interpretiert wird. Es ist auch kein Unterschied, ob man das mit Shortcode oder innerhalb eines Plugins bewältigt.

        Grüße
        Heinz

        Antworten
        1. Robert Beitragsautor

          Hmm, schwierig zu sagen. Hab ich so noch nicht gesehen. Vielleicht irgend eine Theme-Besonderheit mit einem selbstgebautem Caching?

          Antworten
  2. holger

    nach lagem Suchen endlich mal eine Seite gefunden, die auf deutsch und verständlich Grundlegendes erläutert, danke

    Antworten
  3. Reto

    Tolle Seite, Danke für den einfachen Einstieg.
    Zu meiner Verteidigung, bin totaler PHP Neuling…
    Was ich nicht verstanden habe: Ein einzelnes Resultat kann ich ja gut mit der Shortcode Funktion mittels meinem Plugin zurückbringen. Was mache ich aber bei mehreren Ergebnissen aus der DB Abfrage? Wie/wo kann ich diesen Code in meinem Plugin aufrufen und zur Anzeige bringen?
    Habe schon Stunden verplempert, kriege die Ausgabe aber nicht in eine Seite rein. 🙂
    Liebe Grüsse, Reto

    Antworten
    1. Robert Beitragsautor

      Hi Reto,
      du musst die Daten eben mit einer foreach Schleife oder einer for-Schleife durchlaufen und ausgeben. Wie im letzten Code-Beispiel angegeben.

      Antworten
      1. Anonymous

        Hi Robert,
        Danke für die prompte Antwort.
        Ja Schlaufe ist klar, aber in deinem letzten Beispiel lieferst du die Ausgabe per echo Befehl. Dazu müsste ich die Funktion ja direkt aus einer WP Seite heraus aufrufen können, richtig? Das scheint WordPress zu verhindern oder ich habe zumindest noch nicht herausgefunden wie das geht…
        Deshalb habe ich mich gefragt, ob man die Ausgabe in einen Array verpacken könnte und dann zum Anzeigen der Shortcode Funktion übergeben kann, ginge das?
        Viele Grüsse, Reto

        Antworten
        1. Robert Beitragsautor

          Ach, muss ich noch ändern. Ab einer bestimmten WordPress Version geht das mit echo glaub ich nicht mehr.
          Da musst den String in einer Variable speichern und als return Wert zurückgeben, damit es als Plugin funktioniert.

          Ich hoffe, das hilft dir weiter.

          Antworten
  4. Tobi

    Ich hab jetzt eine Tabelle angelegt und würde gerne nur den Inhalt aus einer Zelle in einem WordPress-Beitrag bzw. Seite wiedergeben. Wie kann ich das machen?

    Antworten

Schreibe einen Kommentar

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

Im Rahmen der Kommentarfunktion auf dieser Website werden neben Ihrem Kommentar auch Angaben zum Zeitpunkt der Erstellung des Kommentars und der von Ihnen gewählte Kommentatorenname gespeichert und auf der Website veröffentlicht. Ferner wird Ihre IP-Adresse mitprotokolliert und gespeichert. Diese Speicherung der IP-Adresse erfolgt aus Sicherheitsgründen und für den Fall, dass die betroffene Person durch einen abgegebenen Kommentar die Rechte Dritter verletzt oder rechtswidrige Inhalte postet.
Mehr Informationen zur Datenverarbeitung, der Rechtsgrundlage und Ihren Widerrufsrechten erhalten Sie in unserer Datenschutzerklärung