Website-Icon Badango

.htaccess: Parameter-URLs in statische umschreiben


Während lange URLs mit etlichen GET Parametern früher noch zum Standard gehörten, bevorzugen die meisten Website-Betreiber mittlerweile „schöne“ URLs, die statisch erscheinen, z.B. wie Verzeichnisse oder .html Dateien. Benutzt man ein CMS wie WordPress so ist das in der Regel kein Problem, diese unterstützen solche URLs bereits von Haus aus, doch auch bei einer selbst programmierten Webseite ist das gar nicht so schwierig.


Ich nehme hier bewusst die, auch von WordPress genutzte, Variante mit virtuellen Verzeichnissen als Beispiel, diese lässt sich bei Bedarf vom Prinzip her mit kleinen Anpassungen aber auch ohne weiteres auf z.B. .html Dateien oder ähnliches anwenden.

Die .htaccess Datei

Zunächst der einfachste Teil, nämlich die .htaccess Datei selbst, statt verschiedene Bereiche jeweils mit eigenen Rewrite Rules umzuschreiben (das habe ich selbst bei meiner ersten Webseite vor etwa 14 Jahren auch noch gemacht und hatte am Ende eine .htaccess Datei mit über 20 einzelnen Rewrite Rules…) kann man das nämlich auch mit nur wenigen Zeilen lösen:

RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Dies bedeutet nun ganz einfach, dass sämtliche Requests auf URLs, die nicht auf tatsächlich existierende Dateien oder Verzeichnisse verweisen, immer auf die index.php geleitet werden. Damit das überhaupt funktionieren kann muss bei eurem Server / Webspace natürlich das Modul mod_rewrite aktiviert sein, ob das der Fall ist erfahrt ihr im Zweifel von eurem Hoster.

Die URL in PHP auswerten

Nun muss man natürlich in der index.php auch ermitteln, welche Inhalte denn nun angezeigt werden sollen, ich mache das in der Regel so, dass ich zuerst die aufgerufene URL in einen Array zerlege und dann, je nach Inhalt des Arrays, die passende Datei include bzw die entsprechenden Inhalte aus der Datenbank hole und anzeige.

Dabei sollte man auf jeden Fall überprüfen, ob es die aufgerufene Seite überhaupt gibt, damit man, falls es sie nicht gibt, auch eine 404 Fehlerseite ausgeben kann. Hier mal ein kleines Beispiel wie eine solche index.php aussehen könnte (nähere Erklärungen im Anschluss):

<?php
    $url = explode('/', $_SERVER['REQUEST_URI']);

    if (isset($url[0])) {
        // Prüfen, ob eine entsprechende Datei existiert
        if (file_exists($_SERVER['DOCUMENT_ROOT'] .'/content/'. $url[1] .'.php')) {
            include($_SERVER['DOCUMENT_ROOT'] .'/content/'. file_exists($url[1] .'.php');
        }
        else {
            // Prüfen, ob in der DB ein Eintrag für eine entsprechende Seite existiert
            $sql = "SELECT title, content FROM articles WHERE slug = :slug";
            $stmt = $pdo->prepare($sql);
            $stmt->bindValue(':slug', $url[1], PDO::PARAM_STR);
            $stmt->execute();
            $result = $stmt->fetch();

            if (isset($result->title)) {
                // Hier den Inhalt ausgeben
            }
            else {
                // Angeforderte URL existiert nicht
                header('HTTP/1.0 404 Not Found');
                // Nun eure 404 Seite ausgeben
            }
        }
    }

Gehen wir hier mal von der aufgerufenen URL „/user/profile/blubb/“ aus, dann passiert in diesem Fall folgendes:

Da Arraysbei 0 anfangen zu zählen steht in $url[1] hier „user“, nun wird geprüft, ob eine Datei mit dem Namen user.php existiert, ist dies der Fall, so übernimmt diese die weitere Verarbeitung. Sollte diese Datei nicht existieren so wird in der Datenbank überprüft, ob es dort einen Artikel mit dem „slug“ (der Name, der in der URL steht und jedem Artikel zugeordnet wird) existiert, dann wird entweder dieser Artikel angezeigt oder eine 404 Fehlermeldung ausgegeben.

Eine „user.php“ könnte nun z.B. so aussehen:

<?php
    if ($url[2] == 'profile') {
        // Es soll das Profil eines Users angezeigt werden
        if (isset($url[3])) {
            // Userprofil von dem in $url[3] ("blubb") übergebenen User anzeigen
        }
        else {
            // Eigenes Profil anzeigen
        }
    }
    elseif ($url[2] == 'edit') {
        // Das eigene Profil bearbeiten
    }
    else {
        // 404 anzeigen
    }

So oder so ähnlich können natürlich auch beliebig viele andere Seiten aussehen, für News, Gästebuch oder welche auch immer ihr dort einrichten wollt.
In dem Array $url steht dabei im Key 1 also immer der String nach dem ersten „/“ in der URL, in 2 der String nach dem zweiten „/“ usw, damit könnt ihr dann im Grunde genauso arbeiten, wie sonst mit GET Parametern. Dabei solltet ihr beachten, dass ihr den „Header“ immer erst vor der Ausgabe includet, da man sonst ggf den 404 Statuscode nicht mehr setzen kann.

Dies gilt wohlgemerkt für Webseiten, die man neu erstellt, bei bereits existierenden Webseiten, welche mit GET Parametern arbeiten, kann es durchaus einfacher sein, die URLs mit eigenen Rewrite Rules jeweils „manuell“ umzuschreiben.


Die mobile Version verlassen