oxo888oxo: Seiten-Speed-Test wgen recht großer .htaccess-Datei

0 55

Seiten-Speed-Test wgen recht großer .htaccess-Datei

oxo888oxo
  • htaccess
  1. 0
    Matthias Apsel
    1. 0
      oxo888oxo
      1. 0
        Matthias Apsel
        1. 0
          oxo888oxo
        2. 0
          Der Martin
  2. 3
    Der Martin
    • htaccess
    • webserver
    1. 0
      oxo888oxo
      1. 0
        Der Martin
        1. 0
          oxo888oxo
          1. 0
            Der Martin
            1. 0
              oxo888oxo
              1. 0
                Der Martin
                1. 0
                  Tabellenkalk
                  • menschelei
                  1. 0
                    Der Martin
                    1. 0
                      oxo888oxo
            2. 0
              oxo888oxo
              1. -1
                Matthias Apsel
              2. 1
                Tabellenkalk
                • php
            3. 0
              oxo888oxo
              1. 0
                Der Martin
                1. 0
                  oxo888oxo
                  1. 0
                    Der Martin
                    1. 0
                      oxo888oxo
                      1. 0
                        Der Martin
                        1. 0
                          oxo888oxo
                          1. 0
                            Auge
                            • htaccess
                            • php
                            • webserver
                          2. 0
                            Der Martin
                            1. 0
                              oxo888oxo
                              1. 0
                                Der Martin
                                1. 0
                                  oxo888oxo
                                  1. 0
                                    Der Martin
                                    1. 0
                                      oxo888oxo
                                    2. 0
                                      oxo888oxo
                                      1. 0
                                        Auge
                                        • htaccess
                                        • php
                                        • webserver
                                        1. 0
                                          Jörg Reinholz
                                          1. 0
                                            Der Martin
                                            1. 0
                                              Jörg Reinholz
                                          2. 0
                                            Auge
                                            • meinung
                                            • php
                                            • webserver
                                      2. 0
                                        Der Martin
                                        1. 0
                                          oxo888oxo
                                          1. 0
                                            Der Martin
                                            1. 0
                                              oxo888oxo
                                            2. 0
                                              Jörg Reinholz
                                            3. 0
                                              oxo888oxo
                                      3. 0
                                        Jörg Reinholz
                                        1. 0
                                          oxo888oxo
        2. 0
          Jörg Reinholz
          1. 0
            oxo888oxo
          2. 0
            oxo888oxo
            1. 0
              Jörg Reinholz
              1. 0
                Jörg Reinholz
                1. 0
                  Jörg Reinholz
                  • performance
                  • php
                  1. 0
                    oxo888oxo
    2. 0
      oxo888oxo

Hallo

Ich habe in meiner .htaccess-Datei ca. 1000 Umleitungen per "Redirect 301" angelegt. Die Datei ist jetzt aktuell 65 KB groß.

Nun würde ich gerne mal ermitteln, wie sich das auf die Ladezeit meiner Website auswirkt. Dazu hatte ich überlegt, zwei Speedtests durchzuführen, einmal mit der .htaccess-Datei und einmal mit einer kleinen ohne die ganzen Umleitungen.

Ist das so sinnvoll von mir überlegt? Oder ist das eher quatsch?

Es gibt ja im Nett viele verschiedener solcher Website-Speedtester. Gibt es da einen bestimmten, den Ihr mir empfehlen könnt? Oder sollte ich den Test irgendwie ganz anders durchführen?

Gruß Ingo

  1. Hallo oxo888oxo,

    Ich habe in meiner .htaccess-Datei ca. 1000 Umleitungen per "Redirect 301" angelegt. Die Datei ist jetzt aktuell 65 KB groß.

    Es gibt auch redirectmatch.

    Bis demnächst
    Matthias

    --
    Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
    1. Hallo Matthias

      Es gibt auch redirectmatch.

      Möchtest Du mir damit quasi folgendes zu Verstehen geben?

      Statt für jede Datei eine separate Umleitung per "redirect 301" in die .htaccess-Datei einzutragen, könnte/sollte ich mit redirectmatch und regulären Ausdrücken lieber mehere Dateien am Stück "behandeln".

      Gruß Ingo

      1. Hallo oxo888oxo,

        Statt für jede Datei eine separate Umleitung per "redirect 301" in die .htaccess-Datei einzutragen, könnte/sollte ich mit redirectmatch und regulären Ausdrücken lieber mehere Dateien am Stück "behandeln".

        Genau das. Das verkleinert die .htaccess ungemein. Allerdings habe ich nicht umsonst Martins Antwort positiv bewertet. ;-)

        Bis demnächst
        Matthias

        --
        Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
        1. Hallo Matthias

          Allerdings habe ich nicht umsonst Martins Antwort positiv bewertet. ;-)

          Jo, das scheint mir echt eine extrem gute Idee zu sein. Nun muss ich nur gucken, ob ich das hinbekomme, weil ich ja selbst leider kein PHP drauf habe.

          Gruß Ingo

        2. Hallo Matthias,

          Allerdings habe ich nicht umsonst Martins Antwort positiv bewertet. ;-)

          ja, danke - und so schnell! Ich war ja kaum mit dem Schreiben fertig, da war die +1 schon da. Inzwischen sogar +2.

          Ciao,
           Martin

  2. Hi,

    Ich habe in meiner .htaccess-Datei ca. 1000 Umleitungen per "Redirect 301" angelegt. Die Datei ist jetzt aktuell 65 KB groß.

    ach du liebe Güte ...

    Ich habe keine Ahnung, ob und wie stark sich das tatsächlich auf die Performance des Servers auswirkt. Ein vergleichender Test wäre also durchaus interessant - immerhin wird die .htaccess-Datei bei jedem Zugriff gelesen und ausgewertet.

    Als du neulich von den "toten" Links in deinem Shop gesprochen hast und die alle umleiten wolltest, bin ich nicht davon ausgegangen, dass es so viele wären. Angesichts dieser Masse hätte ich nämlich noch einen anderen Vorschlag.

    Wie wäre es, wenn du alle diese Redirects wieder aus der .htaccess herausnimmst und stattdessen nur ein ErrorDocument für den Status 404 einträgst? Dieses ErrorDocument sei ein PHP-Script, das dann $_SERVER['REQUEST_URI'] gegen eine Liste von URLs prüft und -falls gefunden- die Umeitung macht wie voher per .htaccess (also Status 301 und Location-Header senden), andernfalls brav einen 404 meldet.

    Das hätte den Vorteil, dass nicht bei jedem Request die ganze Litanei an möglichen Redirects geprüft werden müsste, sondern erst dann, wenn tatsächlich etwas angefragt wird, was nicht existiert.

    Schönen Sonntag,
     Martin

    1. Hallo Martin

      Wie wäre es, wenn du alle diese Redirects wieder aus der .htaccess herausnimmst und stattdessen nur ein ErrorDocument für den Status 404 einträgst? Dieses ErrorDocument sei ein PHP-Script, das dann $_SERVER['REQUEST_URI'] gegen eine Liste von URLs prüft und -falls gefunden- die Umeitung macht wie voher per .htaccess (also Status 301 und Location-Header senden), andernfalls brav einen 404 meldet.

      Das hätte den Vorteil, dass nicht bei jedem Request die ganze Litanei an möglichen Redirects geprüft werden müsste, sondern erst dann, wenn tatsächlich etwas angefragt wird, was nicht existiert.

      WOW. das ist ja eine tolle Idee! Danke Dir sehr dafür.

      Leider kann ich selbst kein PHP, darum werde ich ein Script nicht selbst erstellen können. Ich habe gerade schon versucht, per Google herauszufinden, ob so etwas schon mal jemand gemacht hat. Dabei finde ich aber immer nur die Anleitungen, wie man eigene 404-Fehlerseiten erstellt.

      Bzw. weis ich nicht so recht, wie genau ich nach dem Anliegen suchen soll. Hast Du evtl. eine Ahnung, ob so etwas schon mal jemand gemacht hat? Und ob das irgendwo veröffentlicht ist im Netz?

      Gruß Ingo

      1. Hi,

        WOW. das ist ja eine tolle Idee! Danke Dir sehr dafür.

        hör ich doch gern. ;-)

        Leider kann ich selbst kein PHP

        Oh. Ich bin überrascht. Dann werd ich ausnahmsweise mal ein fertiges Code-Beispiel posten, weil das eigentlich trivial ist - wenn man PHP einigermaßen kann.

        <?php
        
        $fehlt = array       // Liste aller URLs, die umgeletet werden sollen
         ( '/shop/abteilung/superprodukt.html',
           '/shop/abteilung/top-angebot.html',
           '/shop/abteilung/knueller.html'
         );
        
        // prüfen, ob ursprünglich angefragte URL im Array $fehlt vorkommt
        if (in_array($_SERVER['REQUEST_URI'], $fehlt))
         { header('Location: http://example.net/suche');   // HTTP-Header für Status 301 mit Redirect senden
           exit;                                           // Script beenden
         }
        
        header('HTTP/1.0 404 Not Found');                  // HTTP-Header für Status 404 senden
        
        // Danach könnte eine zur Site passend ausgestaltete 404-Fehlerseite als gewöhnliches
        // HTML-Dokument folgen
        ?>
        
        <!DOCTYPE html>
        <html>
        ...
        

        Auf dieses PHP-Script würde dann der ErrorDocument-Eintrag für den 404er in der .htaccess verweisen. Ich möchte dich aber bitten, diesen Vorschlag mit Vorsicht zu genießen und lieber abzuwarten, ob da nicht noch jemand anders Schwächen und Unzulänglichkeiten aufzeigt. Ich habe das jetzt bloß mal so schnell-schnell hingeschrieben. Ich denke auch, dass man an der Weiterleitung auf die Suche noch etwas feilen könnte, etwa einen Teil der ursprünglichen URL gleich als Suchbegriff mitgeben.

        So long,
         Martin

        1. Hallo Martin

          <?php
          
          $fehlt = array       // Liste aller URLs, die umgeletet werden sollen
           ( '/shop/abteilung/superprodukt.html',
             '/shop/abteilung/top-angebot.html',
             '/shop/abteilung/knueller.html'
           );
          
          // prüfen, ob ursprünglich angefragte URL im Array $fehlt vorkommt
          if (in_array($_SERVER['REQUEST_URI'], $fehlt))
           { header('Location: http://example.net/suche');   // HTTP-Header für Status 301 mit Redirect senden
             exit;                                           // Script beenden
           }
          
          header('HTTP/1.0 404 Not Found');                  // HTTP-Header für Status 404 senden
          
          // Danach könnte eine zur Site passend ausgestaltete 404-Fehlerseite als gewöhnliches
          // HTML-Dokument folgen
          ?>
          
          <!DOCTYPE html>
          <html>
          ...
          

          Meine Güte, das ist ja großartig. Danke vielmals!

          Ginge es nicht so, dass man in das Array einfach die URLs schreibt, die umgeleitet werden sollen und dazu dann jeweils auch gleich die URL zu der umgeleitet werden soll? Das wäre für mich letztendlich einfacher zu handhaben später.

          Obwohl, das hätte dann ja zur Folge, dass die Prüfung, ob die angefragte URL im Array $fehlt, keinen richtigen Sinn mehr macht. Weil ja auch die Ziel-URLs dann im Array stehen. Oder könnte man das irgendwie so lösen, dass jedes URL-Paar (angefragte URL / Ziel URL) in einer Zeile steht mit einem bestimmten Trennzeichen. Und die Prüfung erfolgt dann bei allen Zeilen nur bis zum Trennzeichen. Hmmmmmm :-)

          Noch was anderes: Wie groß darf denn so ein Array werden? Ich frage, weil da ja letztendlich über 2000 URLs rein sollen.

          Gruß Ingo

          1. Mahlzeit,

            Meine Güte, das ist ja großartig.

            ja danke, die Pizza war nicht übel. ;-)

            Ginge es nicht so, dass man in das Array einfach die URLs schreibt, die umgeleitet werden sollen und dazu dann jeweils auch gleich die URL zu der umgeleitet werden soll? Das wäre für mich letztendlich einfacher zu handhaben später.

            Könnte man, aber ich dachte, dass du generell auf die Suche umleiten wolltest, und aus dem Original-Artikel geeignete Suchbegriffe ableiten möchtest. Also dachte ich, die URL des Original-Artikels müsste eigentlich genug Information hergeben.

            Obwohl, das hätte dann ja zur Folge, dass die Prüfung, ob die angefragte URL im Array $fehlt, keinen richtigen Sinn mehr macht. Weil ja auch die Ziel-URLs dann im Array stehen. Oder könnte man das irgendwie so lösen, dass jedes URL-Paar (angefragte URL / Ziel URL) in einer Zeile steht mit einem bestimmten Trennzeichen. Und die Prüfung erfolgt dann bei allen Zeilen nur bis zum Trennzeichen. Hmmmmmm :-)

            Mir fallen zwei Mthoden ein.

            Die primitive: Zwei getrennte Arrays. Nachteil: Man muss genau darauf achten, dass die beiden immer zueinander passen, man darf sich nicht verzählen. Zweitens reicht die schlichte Prüfung mit in_array() nicht mehr, denn man braucht für den Zugriff auf das Ziel-Array ja nicht nur die Aussage "ja, ist drin", sondern auch noch den Index. Man müsste das Array also "zu Fuß" durchackern und den Index selbst mitzählen.

            Die elegantere: Ein assoziatives Array - also eines, bei dem die Einträge nicht durch einen Index adressiert werden, sondern durch einen alphanumerischen Schlüssel. Dann könnte man die Original-URL als Schlüsselnamen nehmen, und die Ziel-URL als Wert. Etwa so ...

            <?php
            
            $fehlt = array       // Liste aller URLs, die umgeletet werden sollen
             ( '/shop/abteilung/superprodukt.html' => '/shop/abteilung/neuheit.html', // passender Ersatzartikel
               '/shop/abteilung/top-angebot.html'  => '/shop/abteilung/S2000XL.html', // passender Ersatzartikel
               '/shop/abteilung/knueller.html'     => '/suche'                        // keine Entsprechung da
             );
            
            // prüfen, ob ursprünglich angefragte URL als Schlüssel im Array $fehlt vorkommt
            if (isset($fehlt[$_SERVER['REQUEST_URI']])
             { // HTTP-Header für Status 301 mit Redirect senden, Ersatz-URL aus Array holen
               header('Location: http://example.net' . $fehlt[$_SERVER['REQUEST_URI']]);
               exit;                                           // Script beenden
             }
            

            Noch was anderes: Wie groß darf denn so ein Array werden?

            Mir ist nicht bekannt, dass es da eine feste Grenze gibt. Die ergibt sich wohl eher indirekt aus dem Speicher, der einem Script zur Verfügung steht, und das sind in der Regel einige MB.

            Ich frage, weil da ja letztendlich über 2000 URLs rein sollen.

            Okay. Und auch die Performance ist hier nicht mehr so entscheidend, weil dieses Script ja dann nur relativ selten aufgerufen wird.

            So long,
             Martin

            1. Tach Martin

              ja danke, die Pizza war nicht übel. ;-)

              Pizza? Kläre mich auf? Soll ich Dir eine bestellen?

              Könnte man, aber ich dachte, dass du generell auf die Suche umleiten wolltest

              Nein, das ist nur ein Teil meiner Umleitungen. Der andere Teil leitet jeweils auf konkrete Produkte um.

              Also dachte ich, die URL des Original-Artikels müsste eigentlich genug Information hergeben.

              nein, tut sie leider nicht. Bzw. nur für mich. Wenn die original URL z.B. http://example.org/Artikel/pr977.html lautet, weis ich wegen dem "pr", dass es sich damals um eine "Predator"-Produkt gehandelt hat. Wenn es nun aktuell ein Produkt mit der URL http://example.org/produkte/pr977.php gibt, soll direkt zu dieser neuen URL umgeleitet werden. Wenn es aber aktuell das Produkt nicht gibt, soll umgeleitet werden zu http://example.org/search.php?searchwords=Predator.

              Die primitive: Zwei getrennte Arrays. Nachteil: Man muss genau darauf achten, dass die beiden immer zueinander passen, man darf sich nicht verzählen.

              Ja genau das hatte ich so auch überlegt. Und ich fürchte, dass das ganz klar zu Fehleranfällig ist. Bzw. zu mühsam, sich da nie zu verzählen :-)

              Die elegantere: Ein assoziatives Array - also eines, bei dem die Einträge nicht durch einen Index adressiert werden, sondern durch einen alphanumerischen Schlüssel. Dann könnte man die Original-URL als Schlüsselnamen nehmen, und die Ziel-URL als Wert. Etwa so ...

              Ja das hört sich doch prima an. Dann steht ja in einer leicht lesbaren und somit auch leicht bearbeitbaren Liste immer die angefragt URL und die Ziel-URL schön zusammen.

              Okay. Und auch die Performance ist hier nicht mehr so entscheidend, weil dieses Script ja dann nur relativ selten aufgerufen wird.

              Du meinst, weil die ganze Sache ja erst zum Tragen kommt, wenn ein nicht mehr existierenden Produkt aufgerufen wird. Und bei diesen Fällen könnte man mit einer kleinen Performance-Einbuße durchaus leben. Und die Aufrufe der erreichbaren Produkte würden schon mit der bisherigen Performance laufen. Richtig geschnallt von mir?

              Gruß Ingo

              1. Hi,

                ja danke, die Pizza war nicht übel. ;-)

                Pizza? Kläre mich auf? Soll ich Dir eine bestellen?

                nein, ich hatte eben eine, und die war okay - für eine billige Tiefkühlpizza. ;-)

                Okay. Und auch die Performance ist hier nicht mehr so entscheidend, weil dieses Script ja dann nur relativ selten aufgerufen wird.

                Du meinst, weil die ganze Sache ja erst zum Tragen kommt, wenn ein nicht mehr existierenden Produkt aufgerufen wird. Und bei diesen Fällen könnte man mit einer kleinen Performance-Einbuße durchaus leben.

                Genau.

                Und die Aufrufe der erreichbaren Produkte würden schon mit der bisherigen Performance laufen. Richtig geschnallt von mir?

                Mailand. Ähm, Genua. Äh ... Genau.

                So long,
                 Martin

                1. Hallo,

                  nein, ich hatte eben eine, und die war okay - für eine billige Tiefkühlpizza. ;-)
                  ...
                  Mailand. Ähm, Genua. Äh ... Genau.

                  so ganz sicher, dass die Pizza okay war, wär ich mir da jetzt nicht...

                  Gruß
                  Kalk

                  1. Hi,

                    nein, ich hatte eben eine, und die war okay - für eine billige Tiefkühlpizza. ;-)
                    ...
                    Mailand. Ähm, Genua. Äh ... Genau.

                    so ganz sicher, dass die Pizza okay war, wär ich mir da jetzt nicht...

                    also wenn, dann schiebe ich die Schuld eher auf das Bier als auf die Pizza. Weil ... 'ne Pizza ohne Bier dazu geht ja gar nicht. Das wäre wie Kuchen ohne Kaffee.

                    So long,
                     Martin

                    1. Hallo

                      ne Pizza ohne Bier dazu geht ja gar nicht. Das wäre wie Kuchen ohne Kaffee.

                      Ich nehme dann bitte eine Kuchen-Pizza und ein Kaffee mit Schuß (Bier) :-)

                      Gruß Ingo

            2. Hallo

              <?php
              
              $fehlt = array       // Liste aller URLs, die umgeletet werden sollen
               ( '/shop/abteilung/superprodukt.html' => '/shop/abteilung/neuheit.html', // passender Ersatzartikel
                 '/shop/abteilung/top-angebot.html'  => '/shop/abteilung/S2000XL.html', // passender Ersatzartikel
                 '/shop/abteilung/knueller.html'     => '/suche'                        // keine Entsprechung da
               );
              
              // prüfen, ob ursprünglich angefragte URL als Schlüssel im Array $fehlt vorkommt
              if (isset($fehlt[$_SERVER['REQUEST_URI']])
               { // HTTP-Header für Status 301 mit Redirect senden, Ersatz-URL aus Array holen
                 header('Location: http://example.net' . $fehlt[$_SERVER['REQUEST_URI']]);
                 exit;                                           // Script beenden
               }
              

              Obwohl ich ja kein PHP kann, versuche ich gerade mal zu verstehen, was das Script da macht. Im Großen und Ganzen kapiere ich das auch.

              Nur eines kapiere ich nicht. Woher weis das Script denn (nach dem if), dass es in den Array-Zeilen immer nur nach der URL vor dem "=>" suchen soll?

              Und woher weis es, dass die Ziel URL der Teil hinter dem "=>" ist? Ich meine, weil ja da beides mal "$fehlt[$_SERVER['REQUEST_URI']]" steht.

              Gruß Ingo

              1. Hallo oxo888oxo,

                $person = array (
                    name     => 'Mustermann',
                    vorname  => 'Max' 
                );
                

                Bis demnächst
                Matthias

                --
                Das Geheimnis des Könnens liegt im Wollen. (Giuseppe Mazzini)
              2. Hallo,

                Nur eines kapiere ich nicht. Woher weis das Script denn (nach dem if), dass es in den Array-Zeilen immer nur nach der URL vor dem "=>" suchen soll?

                Es handelt sich um ein sogenanntes Assoziatives Array, das du dir als Liste von Variablen vorstellen kannst. VariablenName => VariablenInhalt

                Und woher weis es, dass die Ziel URL der Teil hinter dem "=>" ist? Ich meine, weil ja da beides mal "$fehlt[$_SERVER['REQUEST_URI']]" steht.

                Es wird geguckt, ist die Variable "Ersatz" gesetzt, wenn ja, dann nimm sie (also den Inhalt dieser Variablen).

                Gruß
                Kalk

            3. Hallo Martin

              So, ich habe das nun mal wie folgt umgesetzt:

              <?php
              
                $fehlt = array
                  ( '/produkte/pupifax.php' => 'produkte/sm001.php',
                    '/Artikel/300002.shtml' => '/produkte/300002.php',
                    '/Artikel/avp017.shtml' => '/search.php?searchwords=Alien+vs.+Predator'
                  );
              
                if (isset($fehlt[$_SERVER['REQUEST_URI']])
                  {
                    header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']]);
                    exit;
                  }
               
                 header('HTTP/1.0 404 Not Found');
                 
              ?>
              

              Ich habe den Code ganz oben in meine eigene 505-Fehlerseite gepackt. Nach dem PHP-Code folgt dann ganz normal der html-Code der 404-Fehlerseite. Und natürlich habe ich in meiner .htaccess-Datei auch das hier: ErrorDocument 404 /error404.php

              Aber leider funktioniert das noch nicht. Was habe ich falsch gemacht?

              Ach ja. Zur Zeit ist das nicht online.

              1. Hi,

                So, ich habe das nun mal wie folgt umgesetzt:

                beim ersten Eintrag fehlt der führende '/' für die Ziel-URL. Das gibt beim Zusammensetzen ein Problem.

                <?php
                
                  $fehlt = array
                    ( '/produkte/pupifax.php' => 'produkte/sm001.php',
                      '/Artikel/300002.shtml' => '/produkte/300002.php',
                      '/Artikel/avp017.shtml' => '/search.php?searchwords=Alien+vs.+Predator'
                    );
                
                  if (isset($fehlt[$_SERVER['REQUEST_URI']])
                    {
                      header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']]);
                      exit;
                    }
                 
                   header('HTTP/1.0 404 Not Found');
                   
                ?>
                

                Sieht ansonsten eigentlich gut aus.

                Ich habe den Code ganz oben in meine eigene 505-Fehlerseite gepackt.

                Du meinst 404?

                Nach dem PHP-Code folgt dann ganz normal der html-Code der 404-Fehlerseite. Und natürlich habe ich in meiner .htaccess-Datei auch das hier: ErrorDocument 404 /error404.php

                Aber leider funktioniert das noch nicht. Was habe ich falsch gemacht?

                Du hast nicht erklärt, was 'funktioniert nicht' genau bedeutet. Was hast du genau versucht, was ist genau dabei passiert? Wo bist du tatsächlich gelandet? Mit welchem HTTP-Status? Welchen Wert hat $_SERVER['REQUEST_URI'] exakt?
                Um das rauszufinden, hilft ein

                echo '<pre>*', $_SERVER['REQUEST_URI'], '*</pre>';
                

                am Scriptanfang. Ja, das ergibt ungültiges HTML; ja, dann funktioniert die Umleitung gar nicht mehr; ist ja auch nur zum Debugging. Und die Sternchen sind nur als sichtbare Begrenzer da, damit man sofort sehen kann, ob eventuell noch ein Zeilenumbruch, ein Leerzeichen oder sowas dabei ist.

                Ach ja. Zur Zeit ist das nicht online.

                Das würde uns auch nur bedingt helfen, weil wir nicht in den PHP-Code reingucken könnten.

                So long,
                 Martin

                1. beim ersten Eintrag fehlt der führende '/' für die Ziel-URL.

                  Ups :-) Habe ich nun korrigiert.

                  Du meinst 404?

                  Ja, richtig.

                  Was hast du genau versucht, was ist genau dabei passiert?

                  Ich habe den PHP-Code ganz oben in meine 404-Fehlerseite eingesetzt (noch über <html lang="de" xml:lang="de" xmlns="http://www.w3.org/1999/xhtml">)

                  Ich lande auf einer leeren weißen Seite. Wenn ich mir den Quelltext mit dem Browser anzeigen lasen will, steht da nur eine 1, sonst nichts (Die 1 ist wohl die erste Zeilennummer denke ich).

                  Der Edge Browser zeigt mir einen Fehler 500 an.

                  Mit welchem HTTP-Status? Welchen Wert hat $_SERVER['REQUEST_URI'] exakt?
                  Um das rauszufinden, hilft ein

                  echo '<pre>*', $_SERVER['REQUEST_URI'], '*</pre>';
                  

                  am Scriptanfang.

                  Hab ich gemacht, es bleibt aber weiter bei dem 500 Fehler.

                  Gruß Ingo

                  1. Hi,

                    Ich lande auf einer leeren weißen Seite. Wenn ich mir den Quelltext mit dem Browser anzeigen lasen will, steht da nur eine 1, sonst nichts (Die 1 ist wohl die erste Zeilennummer denke ich).

                    das ist eigenartig. Das würde heißen, der Server sendet ein "leeres" Dokument, also ein Dokument der Länge 0. Das müsste man auch anhand der HTTP-Response-Header nachvollziehen können.

                    Der Edge Browser zeigt mir einen Fehler 500 an.

                    Aua. 500 ist ein "Internal Server Error". Du verlangst vom Apachen etwas, was er nicht kann, nicht versteht oder nicht darf. Hilfreich wäre da ein Blick ins Error-Log des Webservers, da steht in der Regel etwas mehr über die Fehlerursache drin - vorausgesetzt, dein Hoster bietet dir die Möglichkeit.

                    Wenn nicht, muss man im Nebel stochern. Typische Ursachen sind Syntaxfehler in der .htaccess, oder die Verwendung von Direktiven, die der Server-Admin dir nicht erlaubt. Ich will's ja gar nicht glauben, aber es soll tatsächlich Hoster geben, die ErrorDocument nicht zulassen ...

                    echo '<pre>*', $_SERVER['REQUEST_URI'], '*</pre>';
                    

                    am Scriptanfang.

                    Hab ich gemacht, es bleibt aber weiter bei dem 500 Fehler.

                    Klar, wenn ein 500er vorliegt, wird das Script wahrscheinlich gar nicht erst gestartet, weil der Server so weit gar nicht mehr kommt.

                    So long,
                     Martin

                    1. Hallo Martin

                      Aua. 500 ist ein "Internal Server Error". Du verlangst vom Apachen etwas, was er nicht kann, nicht versteht oder nicht darf. Hilfreich wäre da ein Blick ins Error-Log des Webservers, da steht in der Regel etwas mehr über die Fehlerursache drin - vorausgesetzt, dein Hoster bietet dir die Möglichkeit.

                      Ich habe meine Seite bei 1&1 gehostet mit deren normalem "dicken" Hosting-Paket.

                      Typische Ursachen sind Syntaxfehler in der .htaccess, oder die Verwendung von Direktiven, die der Server-Admin dir nicht erlaubt.

                      Würde es zum Testen des Scriptes helfen, wenn ich aus meiner htacess-Datei mal alles rauswerfe bis auf ErrorDocument?

                      Ich will's ja gar nicht glauben, aber es soll tatsächlich Hoster geben, die ErrorDocument nicht zulassen

                      Doch, selbstverständlich lässt 1&1 ErrorDocument zu. Schau hier: https://spaceart.de/produkte/bimmelbammel.php

                      Gruß Ingo

                      1. Mahlzeit,

                        Hilfreich wäre da ein Blick ins Error-Log des Webservers, da steht in der Regel etwas mehr über die Fehlerursache drin - vorausgesetzt, dein Hoster bietet dir die Möglichkeit.

                        Ich habe meine Seite bei 1&1 gehostet mit deren normalem "dicken" Hosting-Paket.

                        ja schön - das beantwortet aber die implizierte Frage nicht. ;-)
                        Was steht denn im Error Log?

                        Typische Ursachen sind Syntaxfehler in der .htaccess, oder die Verwendung von Direktiven, die der Server-Admin dir nicht erlaubt.

                        Würde es zum Testen des Scriptes helfen, wenn ich aus meiner htacess-Datei mal alles rauswerfe bis auf ErrorDocument?

                        Rausnehmen und schrittweise wieder einbauen? Ja, ist eine akzeptable Möglichkeit, wenn man nicht wirklich analytisch vorgehen kann.

                        Ciao,
                         Martin

                        1. Hallo nochmal

                          Hilfreich wäre da ein Blick ins Error-Log des Webservers, da steht in der Regel etwas mehr über die Fehlerursache drin - vorausgesetzt, dein Hoster bietet dir die Möglichkeit.

                          Da steht drin: [29-Feb-2016 14:42:55 Europe/Berlin] PHP Parse error: syntax error, unexpected '{' in ... on line 12

                          Das ist die erste geschweifte öffnende Klammer nach dem "if". Hier nochmal der Code:

                          <?php
                          
                          echo '<pre>*', $_SERVER['REQUEST_URI'], '*</pre>';
                          
                            $fehlt = array
                              ( '/produkte/pupifax.php' => '/produkte/sm001.php',
                                '/Artikel/300002.shtml' => '/produkte/al120.php',
                                '/Artikel/avp017.shtml' => '/search.php?searchwords=Alien+vs.+Predator'
                              );
                          
                            if (isset($fehlt[$_SERVER['REQUEST_URI']])
                              {
                                header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']]);
                                exit;
                              }
                           
                             header('HTTP/1.0 404 Not Found');
                             
                          ?>
                          
                          1. Hallo

                            Da steht drin: [29-Feb-2016 14:42:55 Europe/Berlin] PHP Parse error: syntax error, unexpected '{' in ... on line 12

                            Das ist die erste geschweifte öffnende Klammer nach dem "if". Hier nochmal der Code:

                            <?php
                              if (isset($fehlt[$_SERVER['REQUEST_URI']])
                                {
                                  header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']]);
                                  exit;
                                }
                            ?>
                            

                            Dir fehlt eine schließende Klammer. Merke: Klammern treten in freier Wildbahn immer paarweise auf.

                            if (isset($fehlt[$_SERVER['REQUEST_URI']])
                            

                            Da ist eine Klammer, die die Funktion isset schließt, aber jene für das If-Klammerpaar fehlt.

                            if (isset($fehlt[$_SERVER['REQUEST_URI']]))
                            

                            So wird ein Schuh draus.

                            Tschö, Auge

                            --
                            Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
                            Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
                          2. Hallo Ingo,

                            Hilfreich wäre da ein Blick ins Error-Log des Webservers, da steht in der Regel etwas mehr über die Fehlerursache drin - vorausgesetzt, dein Hoster bietet dir die Möglichkeit.

                            Da steht drin: [29-Feb-2016 14:42:55 Europe/Berlin] PHP Parse error: syntax error, unexpected '{' in ... on line 12

                            Das ist die erste geschweifte öffnende Klammer nach dem "if".

                            ja, jetzt sehe ich's auch: Die öffnende geschweifte Klammer ist für den Parser "unexpected", weil er in der Zeile davor eigentlich noch eine schließende runde Klammer vermisst. Wenn man's ein bisschen auseinanderzieht, wird es etwas deutlicher:

                               if (  isset(  $fehlt[ $_SERVER[ 'REQUEST_URI' ] ]  )    <= schließende Klammer ')' fehlt
                            

                            Ein Editor mit Bracket Matching ist was Feines, da wäre dieser Fehler sofort aufgefallen. ;-)

                            So long,
                             Martin

                            1. Hallo Auge und Martin

                              [...] weil er in der Zeile davor eigentlich noch eine schließende runde Klammer vermisst.

                              Jo ist mir beim Durchzählen auch gerade aufgefallen :) Habe das nun korrigiert. Und was soll ich sagen? Nun funktioniert es !!! Boah da freue ich mich aber echt riesig.

                              Wenn ich das aufgrund eines Statuscode-Checks sehe, wird jetzt umgeleitet 302 -> 200. Wie kann man denn da noch einbauen, dass es eine 301 Umleitung wird? Wäre das wie folgt korrekt?

                              <?php
                              
                                $fehlt = array
                                  ( '/produkte/pupifax.php' => '/produkte/sm001.php',
                                    '/Artikel/300002.shtml' => '/produkte/al120.php',
                                    '/Artikel/avp017.shtml' => '/search.php?searchwords=Alien+vs.+Predator+Preis',
                                    '/produkte/sm001xx.php' => '/search.php?searchwords=Nene+nix+da'
                                  );
                              
                                if (isset($fehlt[$_SERVER['REQUEST_URI']]))
                                  {
                                    header("HTTP/1.1 301 Moved Permanently");
                                    header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']]);
                                    exit;
                                  }
                               
                                 header('HTTP/1.0 404 Not Found');
                                 
                              ?>
                              

                              Gruß Ingo

                              1. Hallo,

                                [...] weil er in der Zeile davor eigentlich noch eine schließende runde Klammer vermisst.

                                Jo ist mir beim Durchzählen auch gerade aufgefallen :)
                                Habe das nun korrigiert.
                                Und was soll ich sagen?
                                Nun funktioniert es !!!
                                Boah da freue ich mich aber echt riesig.

                                ich sag's ja immer wieder: Kaum macht man's richtig, schon geht's. ;-)

                                Wenn ich das aufgrund eines Statuscode-Checks sehe, wird jetzt umgeleitet 302 -> 200. Wie kann man denn da noch einbauen, dass es eine 301 Umleitung wird? Wäre das wie folgt korrekt?

                                Funktioniert möglicherweise auch, ist aber zu umständlich. Ein User-Kommentar im PHP-Handbuch zeigt eine einfachere Lösung auf.

                                Und dazu ...

                                    header('HTTP/1.0 404 Not Found');
                                

                                habe ich auch noch einen Hinweis an fast derselben Stelle gesehen. Ja, ich habe der Einfachheit halber stur HTTP/1.0 hingeschrieben, denn "das wird schon jeder Client und Server richtig verstehen". Aber anscheinend gibt es Fälle, in denen der Apache das in den falschen Hals bekommt.

                                So long,
                                 Martin

                                1. Hallo Martin

                                  Wenn ich das richtig verstehe in dem PHP Handbuch, müsste es also so korrekt sein:

                                  <?php
                                  
                                    $fehlt = array
                                      ( '/produkte/pupifax.php' => '/produkte/sm001.php',
                                        '/Artikel/300002.shtml' => '/produkte/300002.php',
                                        '/Artikel/avp017.shtml' => '/search.php?searchwords=Alien+vs.+Predator+Preis'
                                      );
                                  
                                    if (isset($fehlt[$_SERVER['REQUEST_URI']]))
                                      {
                                        header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']],TRUE,301);
                                        exit;
                                      }
                                   
                                     header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
                                     
                                  ?>
                                  

                                  Liege ich da richtig?

                                  Gruß Ingo

                                  1. Wenn ich das richtig verstehe in dem PHP Handbuch, müsste es also so korrekt sein:

                                          header('Location: https://spaceart.de' . $fehlt[$_SERVER['REQUEST_URI']],TRUE,301);
                                          exit;
                                     
                                       header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
                                    

                                    Liege ich da richtig?

                                    absolut, ja. Denn die Server-Variable $_SERVER['SERVER_PROTOCOL'] enthält einen String, der die in der aktuellen Verbindung verwendete HTTP-Version angibt, also 'HTTP/1.0' oder 'HTTP/1.1'.

                                    Ciao,
                                     Martin

                                    1. Hallo Martin

                                      absolut, ja.

                                      OK prima. Dann werde ich nun mal meine ganzen Umleitungen von der .htaccess-Datei in das 404 Errordokument rüberschaufeln.

                                      Gruß Ingo

                                    2. Hallo

                                      So, nun sind alle meine Umleitungen von der .htaccess-Datei in die 404-Seite gewandert.

                                      Nun tauchen diverse Einträge im Error-Log auf:

                                      [29-Feb-2016 16:47:52 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /.../error404.php:5) in /.../error404.php on line 700

                                      [29-Feb-2016 16:48:00 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /.../error404.php:5) in /.../error404.php on line 700

                                      Was hat es denn damit auf sich?

                                      Gruß Ingo

                                      1. Hallo

                                        Nun tauchen diverse Einträge im Error-Log auf:

                                        [29-Feb-2016 16:47:52 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /.../error404.php:5) in /.../error404.php on line 700

                                        Was hat es denn damit auf sich?

                                        Wenn du bei einem Request selbst Header mitsenden willst, wie du es mit der PHP-Funktion header tust, müssen diese vor jeglicher Ausgabe gesendet werden. Schon die Zeilennummer (700) ist Hinweis (wenn auch nicht Beweis) genug, dass vor dem Sendeversuch in dieser Zeile schon Teile der Ausgabe an den Browser gesendet worden sind.

                                        Der Code, den dir Martin hier gegeben hat, muss also an eine Stelle vor der Generierung des ersten an den Browser gesendeten Zeichens stehen.

                                        Tschö, Auge

                                        --
                                        Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
                                        Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
                                        1. Moin!

                                          Der Code, den dir Martin hier gegeben hat, muss also an eine Stelle vor der Generierung des ersten an den Browser gesendeten Zeichens stehen.

                                          Oder man verwendet ob_start() ... ob_end_flush();

                                          Dann kann man Ausgaben und header munter mixen.

                                          Jörg Reinholz

                                          1. Hi,

                                            Oder man verwendet ob_start() ... ob_end_flush();

                                            Dann kann man Ausgaben und header munter mixen.

                                            kann man, ist aber nicht schön. Und in diesem Fall vermutlich komplett unnötig.

                                            So long,
                                             Martin

                                            1. Moin!

                                              Oder man verwendet ob_start() ... ob_end_flush();

                                              Dann kann man Ausgaben und header munter mixen.

                                              kann man, ist aber nicht schön. Und in diesem Fall vermutlich komplett unnötig.

                                              Du und Auge, ihr habt natürlich beide recht. Das war eher sarkastisch gemeint, aber mit "Dann kann man Ausgaben und header munter mixen." nicht genau genug formuliert, als das man das mitbekommen müsste. Für ein klärendes wegduck hätte es der Möglichkeit bedurft den Beitrag noch zu bearbeiten.

                                              Zu ob_start() ... ob_end_flush();

                                              Es gibt tatsächlich nur wenige Ausnahmefälle, wo das sinnvoll ist. Man kann damit z.B. die Ausgaben bei quasistatischen Inhalten (CMS) cachen oder Wordpress-like nochmal durch ein "Plugin" jagen.

                                              In den meisten anderen Fällen ist die Verwendung nur Ausdruck "unaufgeräumten" Codes.

                                              Erwähnte ich gerade Wordpress? schimpf

                                              Jörg Reinholz

                                          2. Hallo

                                            Der Code, den dir Martin hier gegeben hat, muss also an eine Stelle vor der Generierung des ersten an den Browser gesendeten Zeichens stehen.

                                            Oder man verwendet ob_start() ... ob_end_flush();

                                            Dann kann man Ausgaben und header munter mixen.

                                            Das kann man natürlich auch tun.

                                            Ich bin aber kein Freund dieser Lösung, weil ich im Laufe der Jahre (auch hier) zu oft gesehen habe, dass einem (auch mir) das bei seltenem Einsatz der Technik auf die Füße fallen kann. Einerseits, weil man die Möglichkeit hinnimmt und an anderer Stelle vergisst, sie konkret einzusetzen. Dann kommen Fragen wie „Warum geht das hier, dort aber nicht?“ und andererseits weil man schlimmstenfalls nicht mehr weiß, was man damit bezwecken wollte. Man entsorgt den Code und wundert sich, warum das eigene Programm kaputt gegangen ist.

                                            Meine Meinung: Als Hotfix kann man ob_start und ob_end_flush benutzen, um ein Programm zum Laufen zu bringen oder am laufen zu halten. Mittelfristig fährt man besser mit der Verinnerlichung und Umsetzung der Regel, dass das Senden der Header mit alledem, was im Vorfeld zu erledigen und zu prüfen ist, vor die Generierung der Ausgabe gehört.

                                            Tschö, Auge

                                            --
                                            Wir hören immer wieder, dass Regierungscomputer gehackt wurden. Ich denke, man sollte die Sicherheit seiner Daten nicht Regierungen anvertrauen.
                                            Jan Koum, Mitgründer von WhatsApp, im Heise.de-Interview
                                      2. Hi,

                                        So, nun sind alle meine Umleitungen von der .htaccess-Datei in die 404-Seite gewandert.

                                        Nun tauchen diverse Einträge im Error-Log auf:

                                        [29-Feb-2016 16:47:52 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /.../error404.php:5) in /.../error404.php on line 700

                                        [29-Feb-2016 16:48:00 Europe/Berlin] PHP Warning: Cannot modify header information - headers already sent by (output started at /.../error404.php:5) in /.../error404.php on line 700

                                        du hast doch hoffentlich die Test-Ausgabe am Anfang des Scripts wieder rausgenommen, die ich dir zwischendurch empfohlen habe, um mal zu sehen, was in $_SERVER['REQUEST_URI'] steht? Die Zeile gehört natürlich für den endgültigen Einsatz wieder ersatzlos gestrichen.

                                        Was hat es denn damit auf sich?

                                        Eine HTTP-Ausgabe an den Client besteht aus zwei Teilen: Den HTTP-Headern und dem Nutzinhalt. In PHP kann man HTTP-Header mit der Funktion header() erzeugen (es gibt noch ein paar andere, die indirekt auch HTTP-Header erzeugen, etwa setcookie() oder start_session()).
                                        Sobald das Script nun das erste Stück Nutzinhalt ausgibt, erklärt PHP intern die Header-Phase für erledigt, sendet schon mal alle bis dahin beauftragten Header und kann ab diesem Moment nur noch weiteren Nutzinhalt senden.
                                        Ein weiterer Versuch, doch noch irgendwelche Header zu generieren, wird ignoriert und erzeugt die Notice-Meldung, die du gesehen hast. Die sagt a) in welcher Zeile ein Header erzeugt werden sollte (hier also Zeile 700), und b) wo bereits die eigentliche Ausgabe begonnen hat (Zeile 5).

                                        Ciao,
                                         Martin

                                        1. Hallo Martin, Auge und Jörg

                                          Eine HTTP-Ausgabe an den Client besteht aus zwei Teilen: Den HTTP-Headern und dem Nutzinhalt. [...]

                                          Ah alles klar. Nun raff ich das. Ich glaube ich weis, woran es lag. Da war tatsächlich noch eine Kleinigkeit vor dem PHP-Code. Ich habe das nun korrigiert und werde jetzt beobachten, ob noch weitere Einträge im Error-Log erscheinen.

                                          Gruß Ingo

                                          1. Eine HTTP-Ausgabe an den Client besteht aus zwei Teilen: Den HTTP-Headern und dem Nutzinhalt. [...]

                                            Ah alles klar. Nun raff ich das.

                                            sehr schön. So lernen wir täglich dazu.

                                            Ich glaube ich weis, woran es lag.
                                            Da war tatsächlich noch eine Kleinigkeit vor dem PHP-Code.

                                            Ja, es ist tückisch - denn sogar eine Leerzeile vor dem einleitenden <?php gilt in diesem Sinn schon als Nutzdaten, oder eine Byte Order Mark (BOM) am Dokumentanfang. Möcht' nicht wissen, wie viele Tausende von PHP-Programmierern sich wegen sowas schon einen Wolf gesucht haben!

                                            Ciao,
                                             Martin

                                            1. Hallo Martin

                                              [...] denn sogar eine Leerzeile [...]

                                              Erwischt. Ein solches Schlingelchen hatte sich da oben tatsächlich eingenistet :-)

                                              Gruß Ingo

                                            2. Moin!

                                              Ja, es ist tückisch - denn sogar eine Leerzeile vor dem einleitenden <?php gilt in diesem Sinn schon als Nutzdaten, oder eine Byte Order Mark (BOM) am Dokumentanfang. Möcht' nicht wissen, wie viele Tausende von PHP-Programmierern sich wegen sowas schon einen Wolf gesucht haben!

                                              Allein in Deutschland? Tausende. Die Hilferufe lauten fast unisono "Mein PHP-Skript leitet nicht weiter und sendet nur eine leere Zeile" ... Deshalb hab ich ja ein "Skript zum Sonntag" geschrieben, welches die Leerzeile (und die BOM) vor <?php reparieren kann.

                                              Jörg Reinholz

                                            3. Hallo nochmal an alle hier

                                              Ich danke Euch sehr für die tolle Hilfe. Dadurch habe ich auch wieder viel gelernt. Und die Sache mit den Umleitungen funktioniert nun ganz hervorragend. Auch im Error-Log taucht jetzt nichts mehr auf. Damit ist das nun abgeschlossen würde ich sagen.

                                              Gruß aus Münster Ingo

                                      3. Moin!

                                        on line 700

                                        Du sollst auch nicht Daten und Programm mixen. Das gilt auch dann, wenn Du die Daten so notierst, dass diese als Programm direkt eingelesen werden können.

                                        Mach das wie ich mit include, besser require_once.

                                        Jörg Reinholz

                                        1. Hallo Jörg

                                          Mach das wie ich mit include, besser require_once.

                                          Ah OK. Ja, das werde ich morgen noch umsetzen. Danke für den Hinweis.

                                          Gruß Ingo

        2. Moin!

          Ich würde das etwas anders machen. Folgendes als 404er-Error-Seite hinterlegen:

          ErrorDocument 404 /404.php
          

          und dann

          <?php
          ##404.php
          
          ## ggf. includiert oder sonstige Quelle (DB, ini-File, csv,...)
          $v['foo']='/produkte/abverkauf/foo.html';
          $v['bar']='/produkte/abverkauf/bar.html';
          
          
          # angenommene URI (Test in Konsole)
          if (  empty($_SERVER['REQUEST_URI']) ) {
            ##Tests_
            #$_SERVER['REQUEST_URI']='/shop/abteilung/Ödipus1000+.html';
            $_SERVER['REQUEST_URI']='/shop/Geschenke/foo.html';
            
            
            $_SERVER['SERVER_NAME']='konsole.com';
            $_SERVER['HTTPS']='on';
            $_SERVER['fake']='yes';
          }
          
          $pattern = '/\/([^\/]*)\.html$/';
          
          $dummy=preg_match ( $pattern , $_SERVER['REQUEST_URI'], $matches );
          print_r($matches);
          
          if ($_SERVER['HTTPS'] && 'off' != $_SERVER['HTTPS']) {
              $proto='https://';
          } else {
              $proto='http://';
          }
          
          if ( ! empty($v[$matches[1]]) ) {
              if ( ! empty($_SERVER['fake']) ) {
                  echo  'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] , "\n";
              } else {
                  header( 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] );
              }
          } else {
              if ( ! empty($_SERVER['fake']) ) {
                 echo 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . '/suche.php?q=' . urlencode($matches[1]), "\n";
              } else {
                 $_GET['q']=$matches[1];
                 header('HTTP/1.0 404 Not Found');
                 include_once( $_SERVER['DOCUMENT_ROOT'] . '/suche.php?' );
              }
          }
          

          Für eine reale Webseite natürlich die ganzen Konsolen-Fakes 'herausoperieren'.

          Jörg Reinholz

          1. Oh je, das ist leider entschieden zu hoch für meine sehr sehr bescheidenen PHP-Kenntnisse.

          2. Hallo Jörg

            <?php
            ##404.php
            
            ## ggf. includiert oder sonstige Quelle (DB, ini-File, csv,...)
            $v['foo']='/produkte/abverkauf/foo.html';
            $v['bar']='/produkte/abverkauf/bar.html';
            
            
            # angenommene URI (Test in Konsole)
            if (  empty($_SERVER['REQUEST_URI']) ) {
              ##Tests_
              #$_SERVER['REQUEST_URI']='/shop/abteilung/Ödipus1000+.html';
              $_SERVER['REQUEST_URI']='/shop/Geschenke/foo.html';
              
              
              $_SERVER['SERVER_NAME']='konsole.com';
              $_SERVER['HTTPS']='on';
              $_SERVER['fake']='yes';
            }
            
            $pattern = '/\/([^\/]*)\.html$/';
            
            $dummy=preg_match ( $pattern , $_SERVER['REQUEST_URI'], $matches );
            print_r($matches);
            
            if ($_SERVER['HTTPS'] && 'off' != $_SERVER['HTTPS']) {
                $proto='https://';
            } else {
                $proto='http://';
            }
            
            if ( ! empty($v[$matches[1]]) ) {
                if ( ! empty($_SERVER['fake']) ) {
                    echo  'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] , "\n";
                } else {
                    header( 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] );
                }
            } else {
                if ( ! empty($_SERVER['fake']) ) {
                   echo 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . '/suche.php?q=' . urlencode($matches[1]), "\n";
                } else {
                   $_GET['q']=$matches[1];
                   header('HTTP/1.0 404 Not Found');
                   include_once( $_SERVER['DOCUMENT_ROOT'] . '/suche.php?' );
                }
            }
            

            Auch wenn ich ja nicht so viel davon verstehe. Dein Script sieht ja wesentlich aufwendiger aus als das vom Martin. Spricht denn etwas entscheidendes gegen die Lösung vom Martin?

            Gruß Ingo

            1. Moin!

              Hallo Jörg

              <?php
              ##404.php
              
              ## ggf. includiert oder sonstige Quelle (DB, ini-File, csv,...)
              $v['foo']='/produkte/abverkauf/foo.html';
              $v['bar']='/produkte/abverkauf/bar.html';
              
              
              # angenommene URI (Test in Konsole)
              if (  empty($_SERVER['REQUEST_URI']) ) {
                ##Tests_
                #$_SERVER['REQUEST_URI']='/shop/abteilung/Ödipus1000+.html';
                $_SERVER['REQUEST_URI']='/shop/Geschenke/foo.html';
                
                
                $_SERVER['SERVER_NAME']='konsole.com';
                $_SERVER['HTTPS']='on';
                $_SERVER['fake']='yes';
              }
              
              $pattern = '/\/([^\/]*)\.html$/';
              
              $dummy=preg_match ( $pattern , $_SERVER['REQUEST_URI'], $matches );
              print_r($matches);
              
              if ($_SERVER['HTTPS'] && 'off' != $_SERVER['HTTPS']) {
                  $proto='https://';
              } else {
                  $proto='http://';
              }
              
              if ( ! empty($v[$matches[1]]) ) {
                  if ( ! empty($_SERVER['fake']) ) {
                      echo  'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] , "\n";
                  } else {
                      header( 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . $v[$matches[1]] );
                  }
              } else {
                  if ( ! empty($_SERVER['fake']) ) {
                     echo 'Location: ' . $proto . $_SERVER['SERVER_NAME'] . '/suche.php?q=' . urlencode($matches[1]), "\n";
                  } else {
                     $_GET['q']=$matches[1];
                     header('HTTP/1.0 404 Not Found');
                     include_once( $_SERVER['DOCUMENT_ROOT'] . '/suche.php?' );
                  }
              }
              

              Dein Script sieht ja wesentlich aufwendiger aus als das vom Martin.

              Ok. Ohne die Extras für den Test auf der Konsole:

              <?php
              ##404.php
              
              ## Verschobene:
              $v['foo'] = '/produkte/abverkauf/foo.html';
              $v['bar'] = '/produkte/abverkauf/bar.html';
              
              ## Programm:
              $pattern = '/\/([^\/]*)\.html$/';
              $dummy = preg_match ( $pattern , $_SERVER['REQUEST_URI'], $matches );
              
              if ( ! empty($v[$matches[1]]) ) {
                  if ( $_SERVER['HTTPS'] && 'off' != $_SERVER['HTTPS'] ) {
                      $protoAndHost='https://' . $_SERVER['SERVER_NAME'];
                  } else {
                      $protoAndHost='http://' . $_SERVER['SERVER_NAME'];
                  }
                  header( 'Location: ' . $protoAndHost . $v[$matches[1]] );
              } else {
                  $_GET['q'] = $matches[1];
                  header('HTTP/1.0 404 Not Found');
                  include_once( $_SERVER['DOCUMENT_ROOT'] . '/suche.php' );
              }
              

              Untersucht die URL, gleicht gegen bekannte ($v) Verschiebungen ab, ermittelt, wenn kein Treffer darin den Suchbegriff, sendet also den Header und inkludiert die Suche gleich so, als wäre der Begriff eingegeben worden.

              Der 404er Header wird gebraucht, damit Google erfährt, dass "'Schafskäse mit Löchern' wurde nicht gefunden" besser nicht in den Suchergebnissen erscheint - sonst legt Dir ein Witzbold ein Ei mit Links zu 2.000.000 Produkten, die Du nicht hast.

              Jörg Reinholz

              1. Moin!

                $v['bar']='/produkte/abverkauf/bar.html';

                Noch ein Hinweis. Bei 2000 Einträgen kannst Du zwar schon eine Datenbank nehmen - aber das Skript bzw. die Datei und der Hash dürften unter 200.000 Bytes, also unter 200 Kilobytes, also 0,2 Megabytes bleiben und da fragt man sich noch ob das "not tut".

                Jörg Reinholz

                1. Moin!

                  $v['bar']='/produkte/abverkauf/bar.html';

                  Performance-Test:

                  1. Erzeugen einer Daten-Datei mit 4000 Einträgen:

                  <?php
                  $txt="<?php\n";
                  for ($i=0; $i < 4000; $i++) {
                      $txt .= '$v[\'' . 'quatsch' . $i . '\'] = \'/produkte/abverkauf/quatsch' . $i . '.html\';' . "\n";
                  }
                  file_put_contents('daten.php', $txt);
                  

                  Hat dann 237.786 Bytes (238 KB) und sieht so aus:

                  <?php
                  $v['quatsch0'] = '/produkte/abverkauf/quatsch0.html';$v['quatsch3999'] = '/produkte/abverkauf/quatsch3999.html';
                  

                  Man könnte 12kB sparen indem man pro Zeile zwei Leerzeichen und den Zeilenumbruch weglässt ...

                  2. Eigentliches Test-Skript:

                  <?php
                  define ( 'StartMem', memory_get_usage() );
                  define ( 'StartTime', microtime(1) );
                  
                  include 'daten.php';
                  echo $v['quatsch2000'], "\n";
                  echo 'Zeit    : ', round(1000*(microtime(1) - StartTime)), " ms\n";
                  echo 'Speicher: ', round((memory_get_usage() - StartMem)/1024), " kB\n";
                  

                  Liest Diese ein, gibt einen Eintrag aus der Mitte aus.

                  Ergebnisse:

                  php test_daten.php 
                  /produkte/abverkauf/quatsch2000.html
                  Zeit    : 9 ms
                  Speicher: 570 kB
                  

                  Halte ich für vertretbar.

                  Jörg Reinholz

                  1. Hallo Jörg

                    Halte ich für vertretbar.

                    Hoffentlich bist Du mir da jetzt nicht böse, weil Du Dir soviel Mühe gibst, mir zu helfen. Aber ich kann Dir da leider nicht mehr folgen. Das ist mir leider alles viel zu hoch, wenn ich das mal so sagen darf :-)

                    Ich habe ja jetzt aktuell ca. 1000 Umleitungen in meiner .htaccess-Datei. Und ich denke, es werden sicher noch locker doppelt so viele.

                    Mit http://www.pagespeed.de/ habe ich die Ladezeit meiner Seite nun heute mal mit und mal ohne diese ganzen Umleitungen getestet. Und da gibt es schon einen Unterschied.

                    Da meine Umleitungen verschiedener Art sind, ist für mich die einzige wirklich brauchbare Lösung nach dem Muster, dass ich immer eine angeforderte URL und eine dazugehörige Ziel URL angeben möchte. Also entweder so wie jetzt in der .htaccess-Datei oder eben mit PHP über die Fehlerseite.

                    Gruß Ingo

    2. Hallo

      Ich habe keine Ahnung, ob und wie stark sich das tatsächlich auf die Performance des Servers auswirkt. Ein vergleichender Test wäre also durchaus interessant - immerhin wird die .htaccess-Datei bei jedem Zugriff gelesen und ausgewertet.

      Ja, ich werde das heute mal per http://www.pagespeed.de/ testen. Mal gucken, was dabei herauskommt :-) Ich werde das dann hier berichten.

      Gruß Ingo