CMS mit PHP & MySQL im Eigenbau
Webseiten-Generator

DeveloperIT-ProjekteSoftware

Für einfache Zwecke sind einige kommerzielle und Open-Source-CMS überdimensioniert oder aber nicht speziell genug. Also in die Hände gespuckt und eine Eigenlösung entwickelt!

Mini-CMS

CMS mit PHP & MySQL im Eigenbau

Zugegeben, mit den heute verfügbaren Open-Source-Content-Management-Systemen kann man eigentlich jeden beliebigen Anwendungswunsch erfüllen. Aber im Hintergrund steckt eben immer ein komplexeres System. Deswegen zeigt dieser Artikel, wie Sie ein eigenes Mini-CMS für eine spezielle Anwendung entwickeln. Wichtiger Nebeneffekt ist, dass Sie dadurch lernen und den Aufbau eines solchen Systems verstehen.

Was soll das vorliegende Mini-CMS nun Besonderes können? Es produziert nur eine Art von Artikeln, die sich aus Einzelteilen zusammensetzen. Jeder Teil besteht aus einem Titel und einer Beschreibung. So erstellen und verwalten Sie zum Beispiel eine einfache Newsseite oder eine Anleitung mit Einzelschritten. Dabei soll der eigentliche Autor auch wirklich nur für ihn relevante Artikel bearbeiten können. Ausgegeben wird das Ganze in statischer Form, das heißt als HTML-Seite, die auf dem Webserver gespeichert und zum Download angeboten wird. Hier handelt es sich also weniger um ein klassisches CMS, sondern eher um einen Webseiten-Generator.


PHP 5.1 und PDO

CMS mit PHP & MySQL im Eigenbau

Als Basistechnologie kommt PHP zum Einsatz. Die einfach gestrickte Datenbank basiert auf MySQL. Die Entscheidung für diese Standardkonfiguration fiel recht leicht, da sie durch weite Verbreitung besticht und auf keinem Betriebssystem Probleme macht. Für den Lerneffekt setzt das vorliegende CMS auf die Datenbankabstraktionsklasse PDO (PHP Data Objects).

Der Sinn einer Datenbankabstraktion ist klar: Sie erlaubt die flexible Anbindung an unterschiedliche Datenbanksysteme, schafft also eine Zwischenschicht, die die Unabhängigkeit von der Datenbank garantiert. Die PDO selbst ist zwar nicht unumstritten, wird aber ab PHP 5.1 direkt in PHP integriert. Sie ist also quasi der neue Standard für Datenbankabstraktion.

PHP 5.1 ist aktuell noch im Beta-Stadium, kann aber unter www.php.net/downloads.php#v5.1 heruntergeladen werden. In älteren PHP-Versionen ist die PDO aber natürlich ebenfalls einsetzbar. In PHP 5 befindet sie sich im zusätzlich erhältlichen PECL-Paket und trägt den Namen php_pdo.dll, für ältere Versionen beziehen Sie sie über pecl.php.net.

Eine Anleitung zur Installation finden Sie in der Hilfe unter www.php.net/pdo. Die PDO benötigt für jedes Datenbanksystem, das sie anbinden soll, einen eigenen Treiber. Diesen müssen Sie in der php.ini oder über die Funktion dl() einbinden. Für MySQL ist das:

extension=php_pdo_mysql.dll

Neben MySQL stehen noch Treiber für Firebird, Oracle, MS SQL Server, PostgreSQL und SQLite zur Verfügung. Wenn Sie für das Mini-CMS eine Direktanbindung an eine bestimmte Datenbank realisieren möchten, können Sie das natürlich ebenfalls. Ersetzen Sie dazu die PDO-Anbindung durch die entsprechende Funktionalität. Recht einfach geht dies zum Beispiel mit Mysqli, da diese MySQL-API wie die PDO objektorientiert arbeiten kann und die Methoden nahezu gleich lauten.


Datenbankanbindung

CMS mit PHP & MySQL im Eigenbau

Die Datenbankanbindung mit der PDO ist sehr einfach: Sie benötigen die üblichen Angaben wie Nutzername, Passwort und die DSN. Für MySQL kann Letzteres beispielsweise so aussehen:


$dsn = 'mysql:host=localhost;
dbname=ipro_minicms';

Die Anbindung selbst können Sie in PHP 5 mit einem try-catch-Block fehlerüberprüft durchführen:


try {
$db = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Verbindungsfehler: '. $e->getMessage();
}

Das CMS selbst besteht aus einzelnen Skripts für verschiedene Aufgaben. Damit die Datenbankverbindung überall zur Verfügung steht, landet sie in einer eigenen Datei db.inc.php. Diese wird jeweils mit

include_once('db.inc.php');

eingebunden. Die Datenbank selbst besteht aus nur drei Tabellen: nutzer sichert die Systemnutzer und ist die Basis der Nutzerverwaltung, artikel speichert die einzelnen Artikel und schritt die zugehörigen Arbeitsschritte. schritt erhält als Fremdschlüssel artikel_id, das heißt, jeder Schritt ist mit einer ID versehen, die auf den Artikel verweist, zu dem er gehört.

Je modularer ein Mini-CMS werden soll, desto stärker steigt natürlich die Anzahl der Tabellen. Da hier auf das Speichern einer Navigationshierarchie verzichtet werden kann, reichen die drei Tabellen allerdings problemlos aus.


Login & Nutzerverwaltung

CMS mit PHP & MySQL im Eigenbau

Die Startseite des CMS ist index.php. Dort erhält der Nutzer eine einfache Login-Maske. Das Formular wird per POST versandt. Anschließend prüft das Skript, ob die Felder mit den Namen nutzer und passwort gesetzt sind.

if (isset($_POST['nutzer']) && isset($_POST['passwort'])) {

Nun schreiben Sie das SQL-Statement. Die Werte mit Doppelpunkt davor sind in der PDO so genannte Platzhalter.

$sql = 'SELECT nutzer_id, recht FROM nutzer WHERE name = :nutzer AND passwort = :passwort';

Verwenden Sie die Methode prepare() des Datenbankobjekts, um die Abfrage vorzubereiten. Dabei werden außerdem für SQL-Injections gefährliche Sonderzeichen maskiert:

$abfrage = $db->prepare($sql);

Anschließend definieren Sie die Parameter und führen die Abfrage aus:


$abfrage->bindParam(':nutzer', $_POST['nutzer'], PDO_PARAM_STR);
$abfrage->bindParam(':passwort', $_POST['passwort'],PDO_PARAM_STR);
$abfrage->execute();

Mit der Methode fetch holen Sie sich eine Ergebniszeile. Der Parameter PDO_FETCH_OBJ zeigt an, dass die Zeile als Objekt geliefert wird. Alternativ können Sie mit PDO_FETCH_OBJ das Ergebnis als assoziatives Array erhalten.

if ($ergebnis = $abfrage->fetch(PDO_FETCH_OBJ)) {

Wenn Sie alle Ergebnisse einer Abfrage erhalten möchten, verwenden Sie fetchAll().


Session & Cookies

CMS mit PHP & MySQL im Eigenbau

Wenn die Abfrage ein Ergebnis liefert, es also den Nutzer mit genanntem Nutzernamen und Passwort gibt, setzen Sie eine PHP-Session mit Cookies. Vorsicht: Je nach Einstellung müssen Sie vorab die Session mit session_start() begonnen haben. Außerdem definieren Sie die Nutzer-ID und das Zugriffsrecht des Nutzers als Session-Variable.


$_SESSION['login'] = 'ok';
$_SESSION['nutzer_id'] = $ergebnis->nutzer_id;
$_SESSION['recht'] = $ergebnis->recht;

Wenn der Nutzer vorher von einem bestimmten URL aus dem CMS kam, können Sie ihn auch direkt dorthin weiterleiten.


$url = (isset($_GET['url'])) ? $_GET['url'] : 'admin.php';
header('Location: ' . $url);
}

Nach dem hier gezeigten Muster funktionieren auch die übrigen Datenbankabfragen. Im Folgenden finden Sie die Erläuterungen dazu deswegen nicht mehr so detailliert.

Die Nutzerverwaltung besteht aus einer Datei nutzer.php. Hier können ausschließlich Nutzer mit dem Recht admin oder superadmin andere Nutzer ändern und neue Nutzer hinzufügen. Ein admin darf nur Autoren als Nutzer erstellen, ein superadmin verwaltet als Einziger alle Nutzer. Hier wären viele Erweiterungen denkbar. Zum Beispiel könnte man einem Nutzer die Möglichkeit geben, sich selbst zu registrieren. Oder man speichert die Passwörter verschlüsselt mit einem MD5-Hash, damit sie nicht direkt in der Datenbank ausgelesen werden können.


Administration

CMS mit PHP & MySQL im Eigenbau

Die Administration des Mini-CMS läuft über das Skript admin.php. Es besteht vor allem aus einer Tabelle mit allen Artikeln beziehungsweise für Autoren mit den Artikeln, die ihnen zugeordnet sind. Für jeden Artikel werden dann verschiedene Befehle angeboten: Bearbeiten, Vorschau, Löschen und Speichern. Alle Befehle verweisen jeweils auf eigene Skripts. Die Erkennung für den jeweiligen Artikel läuft über die Artikel-ID:


while($ergebnis = $abfrage->fetch(PDO_FETCH_OBJ)) {
echo '
';
echo ' ' . htmlspecialchars($ergebnis->titel) . '

';
echo ' ' . substr(htmlspecialchars($ergebnis->text), 0, 60) . '

';
echo ' Bearbeiten

';
echo ' Vorschau

';
echo ' Löschen

';
echo ' Speichern

';
echo '

';
}


Artikel bearbeiten

CMS mit PHP & MySQL im Eigenbau

Das Bearbeiten von Artikeln findet in artikel.php statt. Dieses Skript erfüllt eine Doppelrolle: Wenn Sie als id den Wert neu übermitteln, wird damit ein neuer Artikel erzeugt. Das Auslesen der Daten von einzelnen Artikeln übernimmt das Skript artikel_auslesen.inc.php. Damit nicht für jede Funktion die Daten neu aus der Datenbank geholt werden müssen, speichert das Skript die Artikeldaten auch in einer Session-Variablen, deren Name sich aus dem String id und der Artikelnummer zusammensetzt. Vor allem für die einzelnen Schritte ist dies wichtig, da die Bearbeitung dann in den Arrays geschieht, wobei einfach das letzte Element entfernt werden kann.

Wichtig ist beim Zugriff über die Artikel-ID natürlich die Überprüfung, ob ein Skript auch von einem Nutzer bearbeitet werden darf. Admins und Superadmins sind kein Problem, da sie alle Artikel bearbeiten dürfen. Ein wenig schwieriger ist es mit Autoren. Sie dürfen nur ihnen zugewiesene Artikel einsehen und verändern. Dementsprechend prüft das Skript zuerst die Session-Variable recht und ändert gegebenenfalls das SQL-Kommando und die Parameter für Admin und Superadmin:

$sql = 'SELECT * FROM artikel WHERE artikel_id = :artikel_id';

Für normale Autoren sieht das so aus:


$sql = 'SELECT * FROM artikel WHERE nutzer_id = :nutzer_id AND artikel_id = :artikel_id';

Ein weiterer Rechte-Unterschied besteht darin, dass nur Admins und Superadmin den Nutzer für einen Artikel ändern können. Ein Autor ist immer selbst der Nutzer. Diese Unterscheidung wird bei der Ausgabe der Artikeldaten in artikel.php vorgenommen.


Schritte

CMS mit PHP & MySQL im Eigenbau

Auf der Webseite zum Bearbeiten von Artikeln (artikel.php) werden ? falls vorhanden ? auch die Titel der einzelnen Arbeitsschritte ausgegeben. Sie können dann den letzten Schritt entfernen ? hierfür wird aus dem schon erwähnten Array in der Session-Variablen das letzte Element entfernt und dies dann mit der Datenbank synchronisiert.

Für die Bearbeitung der Schritte beziehungsweise für einen neuen Schritt kommt das Skript schritt.php zum Einsatz. Es übernimmt ähnlich wie artikel.php die ID des Artikels und zusätzlich die ID des Schritts.


Vorschau

CMS mit PHP & MySQL im Eigenbau

Wenn der Artikel fertiggestellt ist, können Sie ihn im endgültigen Layout betrachten. Hierzu dient die Vorschau, die in einem neuen Fenster geöffnet wird. Sie nimmt die Inhalte aus den Datenbanktabellen artikel und schritt und fügt diese mit einem Layout zusammen.

An dieser Stelle wird der Einfachheit halber auf ein Template-System verzichtet, das natürlich möglich wäre. Stattdessen wird der HTML-Code direkt in PHP in einer Variablen zusammengesetzt. Hier die ersten zwei Zeilen:


$ausgabe = '' . htmlspecialchars($_SESSION['id'<br /> . $id]['titel']) . '';
$ausgabe .= ' ';


Speichern

CMS mit PHP & MySQL im Eigenbau

Das Speichern funktioniert genauso wie die Vorschau ? beide verwenden als Basis die Datei ausgabe.inc.php. Einziger Unterschied ist, dass die Ausgabe in speichern.php in eine HTML-Datei gespeichert und diese verlinkt wird:


if (file_put_contents('./html/' . $datei, $ausgabe)) {
echo 'Datei gespeichert: ' . $datei . '';
} else {
echo 'Speichern gescheitert.';
}

Bei der Ausgabe haben Sie natürlich alle Formatierungsfreiheiten. So ist es problemlos möglich, ein eigenes Layout außen um die Inhalte herumzupacken. Die ausgegebene Datei können Sie zum Beispiel auch per Mail verschicken oder an einem beliebigen anderen Ort speichern. Vorsicht: Das Verzeichnis, in das Sie die generierten Artikel speichern, sollte vor den Zugriffen der Nutzer geschützt sein, da sonst Autoren bei richtigem Erraten des aus dem Artikeltitel gebildeten Dateinamens auf fremde Artikel zugreifen könnten.


Fazit

CMS mit PHP & MySQL im Eigenbau

Das Mini-CMS ist beliebig erweiterbar: Sie können zu den Schritten Bilder abspeichern und verwalten, Sie haben die Möglichkeit, einen Online-HTML-Editor einzubinden, oder Sie fügen noch Überprüfungsmechanismen für die Nutzereingaben mit Javascript hinzu. Bevor Sie Ihr Mini-CMS aber zu weit ausbauen, greifen Sie vielleicht besser gleich zu einer fertigen Open-Source-Lösung.

Alle Dateien zum Workshop finden Sie auf der Heft-CD und unter listings.internet-pro.de.