Home
Navigation
Impressum
SEO Welten - Webcoding, Editoren, Scripte und Anwendungen
SEO Welten
Buchempfehlungen
 

Serverseitige Redirects: Weiterleitungen statt 404 Fehler

Weiterleitung von fehlerhaften Aufrufen oder alten URLs

Übersicht / Seite - Weiterleitungen:

  1. per Meta-Tag (allgemeine Infos zur Benutzung)
  2. per JavaScript (clientseitige Redirects mit JavaScript)
  3. auf mobile Seiten (eine einfache Umleitung auf mobile Seiten)
  4. mit Bestätigung (Pseudo-Weiterleitung auf mobile Seite mit Bestätigung)
  5. mit PHP (serverseitige Redirects mit PHP)
  6. per htaccess (mit mod_alias und mod_rewrite)
  7. mit mod_rewrite (weitere Beispiele von Weiterleitungen per htaccess)
  8. URL-Rewriting (Umschreibung von URLs mit oder ohne QueryStrings)
  9. Weiterleitung statt 404 (... bei fehlerhaften Aufrufen oder von alten URLs)

Problemstellung

Ob nach einer erfolgten Umstellung eines Softwaresystems oder bei sich häufenden Aufrufen von URLs mit einer fehlerhaften Schreibweise, dass Endergebnis ist oftmals unerwünscht, wenn der Server allzu oft Anfragen nur mit einem 404 HTTP Statuscode beantwortet. Bis zu einer gewissen Anzahl von umzuleitenden URLs würden serverseitige Redirects per htaccess gute Dienste verrichten. Doch wer möchte sich schon seine htaccess mit hunderten oder tausenden von Redirects zumüllen?
Umgehen lässt sich dieses Übel, in dem eine bestehende oder neu anzulegende 404-Fehlerseite mit einem Weiterleitungsscript kombiniert wird. Der Aufwand für ein 404-Weiterleitungsscript hält sich in Grenzen, lediglich das Einpflegen der alten oder fehlerhaften URLs und der neuen URLs sollte gut durchdacht werden. Zumindest in den Fällen, in denen kein Aschenputtel zur Verfügung steht, könnten zum Beispiel die alten und neuen URLs nach der Produkt-ID oder nach anderen Kriterien sortiert werden, bevor diese zum Abruf und zur Auswertung für ein 404-Weiterleitungsscript bereitgestellt werden.

Einzelheiten und mögliche Varianten

Als erster Schritt muss in der htaccess vom obersten Verzeichnis (Root) eine PHP 404-Fehlerseite ausgewiesen werden, falls noch kein entsprechender Eintrag besteht. Dieser Eintrag unterscheidet sich durch nichts von einem normalen Eintrag einer Fehlerseite, außer dass es sich bei der Fehlerseite um eine Seite mit der Extension (Endung) PHP handeln muss.

Eintrag in der htaccess:

ErrorDocument 404 /fehlerseite.php

Variante 1 (mit Array)

Die Bereitstellung der alten oder fehlerhaften URLs und der neuen URLs kann im einfachsten Fall durch die Aufnahme in einem assoziativen Array erfolgen, doch empfiehlt sich diese Vorgehensweise nur bei einer kleineren Anzahl von umzuleitenden URLs.

Erste Variante für Weiterleitung mit fehlerseite.php:

<?php 

$altneu = array(

"/alte-besen.html"  => "/neue-besen.html",
"/alte-pilze.html"  => "/giftpilze.html",
"/alte-frauen.html" => "/junge-frauen.html"
);

if (isset($_SERVER["REQUEST_URI"]) and !empty($_SERVER["REQUEST_URI"])) {

    $alte = $_SERVER["REQUEST_URI"];
    $alte = preg_replace("/[^a-zA-Z0-9.&=\/?_-]/","",$alte);

    $leiteum = "/";     // oder eine beliebige /Seite.html angeben

    if (array_key_exists($alte, $altneu)) {

        $leiteum = $altneu[$alte];
    }

    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://www.example.com".$leiteum);

    exit;
}
else {echo "Es wurde keine URL übergeben.\n";}

?>

Im Beispiel wird zuerst geprüft, ob eine Request-URL dem Script übergeben wurde und ob diese einen Wert besitzt. In der zweiten Zeile werden mit Hilfe der Funktion preg_replace() alle Zeichen ausgefiltert, die nicht zum typischen Aufbau einer URL gehören. Die Zeichenklasse deckt einfache QueryStrings mit ab und kann bei Bedarf ergänzt werden. Sollte sich die zusätzliche Aufnahme des % Prozentzeichens erforderlich machen, so ist ein anderer Weg für die Filterung zu wählen. Bei der Aufnahme weiterer Zeichen sollte die Syntax von regulären Ausdrücken berücksichtigt werden. Mehr dazu unter: RegEx
Im zweiten if-Statemant wird mit der Funktion array_key_exists() kontrolliert, ob die alte oder fehlerhafte URL sich als Schlüssel im Array befindet, bevor der Variablen $leiteum die neue URL als Wert zugewiesen wird. Wurde eine fehlerhafte URL noch nicht in den Array aufgenommen, wird die als Anfangswert in der Variablen $leiteum gespeicherte /Seite.html nicht überschrieben und als Zieladresse für die Weiterleitung verwendet.

Für Variante 2 und 3 (mit MySQL Datenbank)

Wesentlich besser für die Weiterleitung einer größeren Anzahl alter oder fehlerhafter URLs auf neue Zieladressen ist es hingegen, ein Script mit Zugriff auf eine Datenbank zu benutzen. In der Datenbank könnten dann die alten und neuen URls geordnet zur Verfügung gestellt werden. Dazu müssen die alten und neuen URLs zuerst in eine Datenbank eingepflegt werden. Als Beispiel soll eine vorbereitete Tabelle für eine MySQL-Datenbank dienen, die vor einem Test noch in eine bestehende Datenbank importiert werden müsste. Für die tägliche Arbeit sollte hingegen ein Formular mit Zugriff auf die Datenbank für die erforderliche Pflegearbeiten erstellt werden.

Beispiel für tabelle.sql:

CREATE TABLE `weiterleitungen` (
`Alte_URL` tinytext NOT NULL,
`Neue_URL` tinytext
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `weiterleitungen` (`Alte_URL`, `Neue_URL`) VALUES
('/alte-besen.html', '/neue-besen.html'),
('/alte-pilze.html', '/giftpilze.html'),
('/alte-frauen.html', '/junge-frauen.html');

Hinweis: Wer lieber UTF-8 benutzt, sollte bei Charset eine entsprechende Anpassung vornehmen. Anzumerken bleibt weiterhin, das InnoDB bei älteren MySQL-Versionen noch nicht als Standard-Engine installiert wurde und die Angabe eventuell gegen MyISAM ausgetauscht werden muss. Ohne Angabe einer Engine kann die Tabelle jedoch ebenfalls erstellt werden.

Variante 2 (klassische Variante)

Um auf eine MySQL Datenbank zugreifen zu können, bietet PHP unterschiedliche Bibliotheken mit ebenso unterschiedlichen Erweiterungen und Schnittstellen an. Mindestvoraussetzung für die Nutzung der erweiterten Zugriffsmöglichkeiten ist die MySQL Version 4.1 oder höher und die PHP Version 5 oder höher. Als erstes Beispiel soll eine klassische Variante dienen. Im Code-Listing wurde mysql verwendet, doch mit geringfügigen Änderungen lässt sich dieser Code auf eine Variante mit mysqli im prozeduralen Stil umstellen.

Zweite Variante für fehlerseite.php:

<?php

if (isset($_SERVER["REQUEST_URI"]) and !empty($_SERVER["REQUEST_URI"])) {

    $alte = $_SERVER["REQUEST_URI"];
    $alte = preg_replace("/[^a-zA-Z0-9.&=\/?_-]/","",$alte);

    @mysql_connect("localhost", "root", "passwort") or die ("F1");
    @mysql_select_db("datenbank") or die ("F2");

    $rufeab  = "SELECT Neue_URL FROM weiterleitungen WHERE Alte_URL='".$alte."'";
    $leiteum = "/";    // alternatives Ziel für Weiterleitung angeben

    if (mysql_query($rufeab)!== false) {

        $wum = mysql_query($rufeab);
        $row = mysql_fetch_assoc($wum);
        $neu = trim(htmlspecialchars($row["Neue_URL"],ENT_QUOTES));

        if(!empty($neu)) {$leiteum = $neu;}
    }
    mysql_close();

    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://www.example.com".$leiteum);

    exit;
}
else {echo "Es wurde keine URL übergeben.\n";}

?>

Wie im ersten Beispiel, so wird auch in dieser Variante zuerst geprüft, ob eine Request-URI dem Script übergeben wurde und ob diese einen Wert besitzt. Sollte dies der Fall sein, wovon auszugehen ist, wird der Wert mit preg_replace() gefiltert, eine Verbindung zum MySQL-Server aufgebaut und die angegebene Datenbank ausgewählt. Mit mysql_query() wird eine Abfrage gestartet. Ist die übergebene URL in der Datenbank gespeichert und wurde dieser URL eine neue URL zugeordnet, wird die neue URL ausgegeben.
Ist die übergebene URL hingegen nicht oder noch nicht in der Datenbank gespeichert oder wurde einer alten oder fehlerhaften URL bisher keine neue URL zugeordnet, wird der Wert der Variablen "$leiteum", in der als Wert ein alternatives Ziel für eine Umleitung gespeichert ist, hingegen nicht überschrieben.

Variante 3 (mysqli mit Prepared Statement)

Das dritte Code-Listing unterscheidet sich von der zweiten Variante nur dadurch, dass diese Variante auf MySQLi aufsetzt, im objektorientierten Stil geschrieben wurde und ein Prepared Statement verwendet wird. Wie weiter oben bereits beschrieben, auf eine MySQL-Datenbank kann ein Programmierer über unterschiedliche Erweiterungen und Schnittstellen zugreifen, (wie über die mysqli-Erweiterung), vorausgesetzt die erforderlichen Bibliotheken und Erweiterungen wurden auf dem Server installiert und aktiviert. Mit phpinfo() lässt sich jedoch einfach überprüfen, ob der MySQLi Support ermöglicht ist.

Dritte Variante für fehlerseite.php:

<?php

if (isset($_SERVER["REQUEST_URI"]) and !empty($_SERVER["REQUEST_URI"])) {

    $alte = $_SERVER["REQUEST_URI"];
    $alte = preg_replace("/[^a-zA-Z0-9.&=\/?_-]/","",$alte);

    $leiteum = "/";          // alternative Zielseite angeben

    @$db = new mysqli("localhost", "root", "passwort", "datenbank");

    if (mysqli_connect_error() != Null) { die ("FC");}

    if ($rufab = $db->prepare("SELECT Neue_URL FROM weiterleitungen WHERE Alte_URL=?")) {

        $rufab->bind_param("s", $alte);
        $rufab->execute();
        $rufab->bind_result($neue_url);
        $rufab->fetch();
        $rufab->close();
        
        $neue = trim(htmlspecialchars($neue_url,ENT_QUOTES));

        if(!empty($neue)) {$leiteum = $neue;}        
    }
    $db->close();

    header("HTTP/1.1 301 Moved Permanently");
    header("Location: http://www.example.com".$leiteum);

    exit;
}
else {echo "Es wurde keine URL übergeben.\n";}

?>

Bei der Programmierung mit mysqli im prozeduralen Stil gibt es praktisch nur geringfüge Unterschiede zum "klassischen" Stil mit mysql. Etwas anders sieht die Angelegenheit im objektorientierten Stil aus und zumindest ein Prepared Statement ist doch reichlich gewöhnungsbedürftig, werden doch im Statement Fragezeichen als Platzhalter verwendet. Weiterhin muss bei bind_param der Datentyp angeben werden, im Beispiel ein kleines "s" für String.

Die vorgestellten Beispiele sind einfach gehalten, sollten jedoch voll und ganz ihren Zweck erfüllen und selbst fehlerhafte Aufrufen in Masse, zum Beispiel verursacht durch veraltete URLs, sauber per 301 HTTP Statuscode weiterleiten.

Browser ... | Auf mobile ... | Mit PHP ... | Weitere | sprechende URLs «

 
Navigation

Finden und
gefunden werden ...


Zukunftsaussichten


- Optimierung -

 

Webcoding

Übersicht


Web Services


Tutorials &
diverse Listings

und vieles mehr...


Copyright © 2006 - Verlag Horst Müller - Stendal | Datenschutz | Nutzungsbedingungen