PHP für Anfänger: Erstellen Sie Ihr erstes einfaches CMS

Avatar of Jason Lengstorf
Jason Lengstorf am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Die Magie von PHP + MySQL

Man kann mit Sicherheit sagen, dass fast jede aktuelle Website heutzutage irgendeine Form von Content-Management-System (CMS) verwendet. Obwohl es eine Menge großartiger kostenloser Optionen gibt, die uns ein CMS zur Verfügung stellen, um eine Website zu betreiben (WordPress, Drupal usw.), schadet es nicht, unter die Haube zu schauen und ein Gefühl dafür zu bekommen, wie diese Systeme funktionieren.

Um uns als Backend-Entwickler einzuarbeiten, erstellen wir eine einfache PHP-Klasse, die Folgendes tut:

  • Erstellt eine Datenbank
  • Stellt eine Verbindung zu einer Datenbank her
  • Zeigt ein Formular mit zwei Feldern an
  • Speichert die Formulardaten in der Datenbank
  • Zeigt die gespeicherten Daten aus der Datenbank an

Dateien herunterladen

Diese Klasse soll Ihnen ein Gefühl dafür vermitteln, wie PHP und MySQL zusammenarbeiten, und die Grundlagen eines CMS zeigen. Ich werde Erklärungen zu einigen sehr grundlegenden Programmierkonzepten überspringen. Wenn Sie sich also an irgendeiner Stelle verloren fühlen, sehen Sie sich den Kurs Diving into PHP an und verschaffen Sie sich einen Crashkurs in PHP. Ich versuche jedoch, niemanden zu verlieren, versprochen.

Erstellen der Klasse

Unser erster Schritt besteht darin, die Klasse einfach in einer Datei namens „simpleCMS.php“ anzulegen, damit wir einen Fahrplan haben, mit dem wir arbeiten können.

<?php

class simpleCMS {
  var $host;
  var $username;
  var $password;
  var $table;

  public function display_public() {
    
  }

  public function display_admin() {
    
  }

  public function write() {
    
  }

  public function connect() {
    
  }

  private function buildDB() {
    
  }
}

?>

Wie Sie sehen, erstellen wir eine Klasse mit vier Variablen und fünf Methoden. Ich habe mich für den objektorientierten Ansatz von PHP entschieden, da er bei großen Projekten für saubereren Code sorgt und meiner Meinung nach einfach eine gute Vorgehensweise ist.

Die Variablen

In diesem Fall dienen alle vier Variablen zum Herstellen der Verbindung zur Datenbank: $host, $username, $password und $table stellen einen Pfad und Zugriff auf unsere Datenbank auf dem Server bereit. Vorerst lassen wir diese leer und widmen uns unserer Datenbank, die durch die Methode buildDB() konstruiert wird.

Erstellen der Datenbank

private function buildDB() {
    $sql = <<<MySQL_QUERY
        CREATE TABLE IF NOT EXISTS testDB (
            title	VARCHAR(150),
            bodytext	TEXT,
            created	VARCHAR(100)
    )
    MySQL_QUERY;

    return mysql_query($sql);
}

Diese Funktion führt einen MySQL-Befehl aus, der die Datenbank überprüft, obtestDBexistiert. Wenn ja, gibt sie einfach eine Erfolgsmeldung aus; wenn nicht, erstellt sie unsere Tabelle und weist drei Spalten zum Speichern von Daten zu.

Verbindung zur Datenbank herstellen

Jetzt, da wir eine Funktion zum Erstellen unserer Tabelle haben, erstellen wir die Funktion, die sich mit unserer Datenbank verbindet.

public function connect() {
    mysql_connect($this->host,$this->username,$this->password) or die("Could not connect. " . mysql_error());
    mysql_select_db($this->table) or die("Could not select database. " . mysql_error());

    return $this->buildDB();
}

Wir rufen mysql_connect() auf, um uns mit unserer Datenbank zu verbinden, und dann mysql_select_db(), um sicherzustellen, dass wir unsere Daten am richtigen Ort speichern. Beide Funktionen werden vom Befehl die() begleitet, der im Wesentlichen besagt: „Für den Fall, dass diese Funktion fehlschlägt, stoppe die Ausführung dieses Skripts und zeige eine Meldung an.“

Unsere connect()-Funktion stellt die Verbindung zur Datenbank her und weist uns in die richtige Richtung, dann führt sie unsere buildDB()-Funktion aus. Erinnern Sie sich an den grammatikalisch ungeschickten Teil „IF NOT EXISTS“ unseres MySQL-Befehls? Da wir diese Funktion bei jedem Laden der Seite ausführen werden, müssen wir sicherstellen, dass wir unsere Datenbank nicht bei jedem Funktionsaufruf überschreiben, und genau das erfordert dieser Ausdruck.

Erstellen des Formulars

Wir haben also eine Datenbank. Jetzt müssen wir nur noch Dinge hineinlegen!

public function display_admin() {
    return <<<ADMIN_FORM

    <form action="{$_SERVER['PHP_SELF']}" method="post">
      <label for="title">Title:</label>
      <input name="title" id="title" type="text" maxlength="150" />
      <label for="bodytext">Body Text:</label>
      <textarea name="bodytext" id="bodytext"></textarea>
      <input type="submit" value="Create This Entry!" />
    </form>

ADMIN_FORM;
}

Auch dies ist eine sehr einfache Funktion. Wenn sie aufgerufen wird, gibt sie einfach das HTML-Markup zurück, um unser Formular zu erstellen. Sie werden jedoch im action-Attribut des form-Elements feststellen, dass ich die Variable $_SERVER['PHP_SELF'] verwendet habe. Dies ist im Wesentlichen eine Verknüpfung, die auf die Datei verweist, die Sie gerade verwenden (in unserem Fall ist es display.php). Dies ist nützlich, wenn Sie Ihren Code auf einer Website wiederverwenden und diese Funktion nicht unbedingt für jede Seite neu schreiben möchten.

Ich werde mir auch einen Moment Zeit nehmen, um über die Methode zu sprechen, die ich verwende, um das HTML zurückzugeben. Es ist ein Format, das in PHP als HEREDOC-Syntax bezeichnet wird, und ich liebe es.

Der Hauptvorteil von HEREDOC besteht darin, dass es Ihnen ermöglicht, Formatierungen in Ihre Ausgabe einzufügen. Dies ist außerordentlich nützlich für Leute wie mich, die Probleme mit unübersichtlichem Quellcode haben. Weitere Informationen zur HEREDOC-Syntax und Ähnlichem finden Sie im PHP-Handbuch.

Speichern der Daten in der Datenbank

Unser Formular ermöglicht uns die Eingabe von Informationen, aber wie speichern wir sie? Hier kommt unserewrite()Methode ins Spiel.

public function write($p) {
    if ( $p['title'] )
      $title = mysql_real_escape_string($p['title']);
    if ( $p['bodytext'])
      $bodytext = mysql_real_escape_string($p['bodytext']);
    if ( $title && $bodytext ) {
      $created = time();
      $sql = "INSERT INTO testDB VALUES('$title','$bodytext','$created')";
      return mysql_query($sql);
    } else {
      return false;
    }
}

Beginnen wir mit dem Funktionsaufruf selbst – wir übergeben dieser Funktion eine Variable, was wir bisher noch nicht getan haben. Unsere Variable $p enthält die Informationen, die über die post-Methode von unserem Formular gesendet werden.

Innerhalb der Funktion beginnen wir mit einer bedingten Anweisung, die überprüft, ob der Wert title im Formular festgelegt wurde, bevor es gesendet wurde. Wenn dies der Fall ist, legen wir unsere Variable $title auf den Wert $_POST['title'] fest (HINWEIS: Wir verwenden die Funktion mysql_real_escape_string() als Vorsichtsmaßnahme gegen potenziell gefährliche Eingaben, was wichtig ist, wenn Sie etwas erstellen, das Benutzereingaben zulässt). Wenn $_POST['title'] nicht festgelegt wurde, überspringen wir diese Zeile und lassen die Variable $title unbestimmt.

Dieser Vorgang wird für unsere zweite Eingabe wiederholt, und dann werden beide Variablen überprüft, um sicherzustellen, dass nichts leer ist, bevor sie in der Datenbank gespeichert werden. Wenn beide Variablen festgelegt sind, legen wir die Variable $created mit dem aktuellen Unix-Zeitstempel fest, den wir verwenden, um unsere Einträge chronologisch zu sortieren, wenn wir sie in Zukunft anzeigen.

Wir haben jetzt drei Variablen, und da wir Überprüfungen durchgeführt haben, wissen wir, dass alle drei Variablen nicht leer sind. Jetzt können wir unsere MySQL-Abfrage schreiben, die den Eintrag in der Datenbank speichert!

Anzeigen der Informationen aus der Datenbank

Jetzt, da wir die Möglichkeit haben, Informationen in unsere Datenbank einzufügen, müssen wir eine Möglichkeit schaffen, diese Informationen wieder herauszuholen. Hier kommt display_public() ins Spiel. Dies ist bei weitem die komplexeste unserer Methoden, also nehmen wir uns wirklich Zeit, um herauszufinden, was darin vor sich geht.

public function display_public() {
    $q = "SELECT * FROM testDB ORDER BY created DESC LIMIT 3";
    $r = mysql_query($q);

    if ( $r !== false && mysql_num_rows($r) > 0 ) {
      while ( $a = mysql_fetch_assoc($r) ) {
        $title = stripslashes($a['title']);
        $bodytext = stripslashes($a['bodytext']);

        $entry_display .= <<<ENTRY_DISPLAY

    <h2>$title</h2>
    <p>
      $bodytext
    </p>

ENTRY_DISPLAY;
      }
    } else {
      $entry_display = <<<ENTRY_DISPLAY

    <h2>This Page Is Under Construction</h2>
    <p>
      No entries have been made on this page. 
      Please check back soon, or click the
      link below to add an entry!
    </p>

ENTRY_DISPLAY;
    }
    $entry_display .= <<<ADMIN_OPTION

    <p class="admin_link">
      <a href="{$_SERVER['PHP_SELF']}?admin=1">Add a New Entry</a>
    </p>

ADMIN_OPTION;

    return $entry_display;
  }

Das erste, was man beim Lesen aus einer Datenbank beachten sollte, ist die Art und Weise, wie PHP und MySQL miteinander interagieren. Zuerst stellen wir der Datenbank eine Frage (Query), auf die sie mit einem Ergebnis (Resource) antwortet. Dieses Ergebnis ist jedoch erst dann wirklich nützlich, wenn wir es mit einer von mehreren Methoden dekodiert haben, die die darin enthaltenen Informationen in eine verwendbare Form (Array) „abrufen“ oder organisieren.

Unsere allererste Aktion in der obigen Funktion ist das Einrichten unserer Abfrage in der Variable $q. Der Sternchen-Operator (*) in MySQL bedeutet „alles“, daher fragt unsere Abfrage die Datenbank, ob alles aus Einträgen in der Tabelle testDB in umgekehrter chronologischer Reihenfolge ausgewählt werden soll, beschränkt auf die ersten drei zurückgegebenen Einträge.

Nachdem die Abfrage definiert ist, senden wir sie mithilfe der Funktion mysql_query() an die Datenbank. Die resultierende Ressource wird in der Variable $r gespeichert. Hier wird es etwas knifflig.

Wir führen nun eine bedingte Anweisung aus, die besagt: „WENN mysql_query() nicht fehlgeschlagen ist UND WENN die Anzahl der zurückgegebenen Einträge größer als null war, verarbeite das Ergebnis, ODER ANDERNFALLS zeige eine Standardnachricht an.“

Wenn $r Einträge aus der Datenbank enthält, müssen wir diese Daten nun „abrufen“. Informationen aus der Datenbank werden als Array zurückgegeben, das ähnlich wie die Datenbanktabelle selbst organisiert ist. Die Funktion mysql_fetch_assoc() nimmt die Ressource und unterteilt jeden Eintrag in ein assoziatives Array (das bedeutet, dass, wenn wir das Ergebnis von mysql_fetch_assoc() in der Variable $a speichern, die Daten des Eintrags über die Spaltennamen in der Datenbank zugänglich sind, d. h. $a['title']).

Allerdings liefert uns mysql_fetch_assoc() nur einen Eintrag auf einmal. Um alle zurückgegebenen Einträge zu erhalten, müssen wir eine while-Schleife verwenden. Im Wesentlichen sagen wir: „SOLANGE $r noch Werte enthält, die wir noch nicht verwendet haben, hole den nächsten Eintrag in der Reihe und führe die folgenden Aktionen damit aus.“

In diesem Fall überprüfen wir den Eintrag, um sicherzustellen, dass Daten zurückgegeben wurden, und entfernen dann die Schrägstriche, die hinzugefügt wurden, als wir die Informationen mithilfe von stripslashes() in der Datenbank gespeichert haben. Danach verpacken wir die Variablen einfach in etwas HTML und, voila! wir haben bildschirmfertigen Inhalt!

Als letzten Schritt fügt der Code unten einen Link hinzu, über den Benutzer einen Eintrag hinzufügen können. Es ist erwähnenswert, dass der Operator „.=“ in der while-Schleife und beim Erstellen des Links „Add a New Entry“ verwendet wird; eine Funktion kann nur eine Variable zurückgeben, daher müssen wir die neuen Informationen an die vorhandene Variable anhängen. Wenn wir nur das Gleichheitszeichen („=“) verwenden würden, würden wir vorhandene Daten überschreiben und am Ende nur einen Link zum Formular und keinen Inhalt haben.

Sie haben also Ihre erste CMS-Klasse geschrieben! Sie können ganz einfach Daten in eine Datenbank schreiben und daraus abrufen. Jetzt müssen Sie es nur noch ausprobieren!

Verwenden der Klasse

Um unsere Klasse zu verwenden, müssen wir eine separate Datei erstellen. Ich nenne sie „display.php“, die ich im Haupt-Webordner speichere, wobei unsere Klasse als „simpleCMS.php“ in einem Ordner namens „_class“ im Hauptordner gespeichert wird. Zunächst erstellen wir einfach ein Dokument mit normalem HTML.

<!DOCTYPE html>
<html lang="en">

  <head>
    <title>SimpleCMS</title>
  </head>

  <body>

  </body>

</html>

Um unsere Klasse zu verwenden, müssen wir nur ein wenig PHP zwischen die Body-Tags einfügen

<?php

  include_once('_class/simpleCMS.php');
  $obj = new simpleCMS();
  $obj->host = 'database.host.net';
  $obj->username = 'DB1234567';
  $obj->password = 'DBpassword';
  $obj->table = 'DB1234567';
  $obj->connect();

  if ( $_POST )
    $obj->write($_POST);

  echo ( $_GET['admin'] == 1 ) ? $obj->display_admin() : $obj->display_public();

?>

Zuerst müssen wir die Klasse mithilfe der Funktion include_once() einbinden. Dann müssen wir unser Objekt instanziieren, damit unser Code weiß, was los ist. Drittens legen wir alle Variablen fest, über die wir am Anfang dieses Tutorials gesprochen haben. Sie müssen alle diese Werte durch die Informationen ersetzen, die Sie von Ihrem eigenen Server oder Hostinganbieter erhalten. Und viertens stellen wir mithilfe der Methode connect() eine Verbindung zu unserer Datenbank her.

Nachdem wir uns mit der Datenbank verbunden haben, überprüfen wir, ob $_POST-Informationen vorhanden sind. Dies liegt daran, dass wir dieselbe Datei für die Eingabe, Verarbeitung und Anzeige von Informationen verwenden. Wenn etwas über $_POST übergeben wurde, führen wir die Funktion write() aus, um es zu validieren und in der Datenbank zu speichern. Dann verwenden wir eine Abkürzung, um eine bedingte Anweisung auszuführen. Im Wesentlichen sagen wir: „WENN $_GET['admin'] auf 1 gesetzt ist, zeige das Formular mithilfe von display_admin() an, ODER ANDERNFALLS zeige mir die gespeicherten Einträge mithilfe von display_public() an.“

Und das war’s! Sobald Sie ein Gefühl dafür bekommen, können Sie mit dieser Art von grundlegender Programmierung die totale Kontrolle über die von Ihnen erstellten Websites ausüben, egal ob Sie sich entscheiden, sich wirklich einzuarbeiten und Ihr eigenes CMS-Framework zu erstellen, oder einfach ein vorhandenes CMS verbessern, indem Sie beispielsweise ein WordPress-Plugin schreiben.

Wirklich, wenn es um modernes Webdesign geht, sollten Sie zumindest einige Kenntnisse darüber haben, wie die Dinge hinter dem Vorhang funktionieren – das Verständnis, wie eine Website funktioniert, ermöglicht es Ihnen besser, Websites zu entwerfen, die eine flüssigere Integration von Form und Funktion aufweisen. Und außerdem schadet es Ihrer Glaubwürdigkeit definitiv nicht, PHP und MySQL in Ihren Lebenslauf aufzunehmen …

Dateien herunterladen

Jason Lengstorf leitet Ennui Design, ein freiberufliches Design- und Entwicklungsunternehmen. Er hat eine Vorliebe dafür, benutzerdefinierte Anwendungen von Grund auf neu zu erstellen, einschließlich seines eigenen Content-Management-Systems. Wenn er nicht an seine Tastatur gefesselt ist, trägt er wahrscheinlich Cowboy-Hemden, macht Kreuzheben oder tut so, als wüsste er etwas über Wein.

Wichtiger Hinweis

Dieser Code wurde nur zu Demonstrationszwecken geschrieben. In den Kommentaren wurden mehrere Sicherheitslücken aufgezeigt, auf die ich in Teil zwei dieser Tutorialreihe eingegangen bin Anmerkung des Redakteurs: Es gibt keinen Teil zwei dieser Reihe mehr. Jason empfiehlt sein Buch PHP for Absolute Beginners als Ressource für Best Practices. Dennoch würde ich dringend raten, es nicht für Produktions-Websites ohne weitere Tests zu verwenden.

Ich habe einige Sicherheitsgrundlagen abgedeckt, aber es können weitere Probleme bestehen. Weitere Informationen zu Sicherheitsrisiken und sicherem PHP-Code finden Sie hier. Bitte lesen Sie dies durch, bevor Sie diesen Code auf Ihrem Server implementieren, um potenzielle Sicherheitslücken zu vermeiden.