Rainer: .htaccess

Hallo allerseits,

mit:

RewriteEngine on
RewriteRule ^(.*).html$ index.php

leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei. Im Webverzeichnis gibt es einen Ordner /statistik in welchem ebenfalls eine .html liegt. Was muss ich in der .htaccess schreiben das diese Datei nicht auf index.php geleitet wird bzw. ist das über die .htaccess im Document Root des Webverzeichniss überhaut möglich?

Gruß Rainer

  1. Hi!

    RewriteEngine on
    RewriteRule ^(.*).html$ index.php
    leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei.

    Nein, das arbeitet fehlerhaft, nur dass du den Fehlerfall anscheinend nicht ausreichend getestet hast. Der Punkt ist ein Sonderzeichen. Er kann nicht einmal für ein beliebiges Zeichen stehen und einmal für sich selbst, ohne dass konkret gekennzeichnet ist, was genau gewünscht ist. In deinem Fall steht der zweite Punkt ebenfalls für ein beliebiges Zeichen. Ihn auf einen Punkt einzuschränken verlangt, ihn mit einem vorangehenden Backslash zu notieren.

    Im Webverzeichnis gibt es einen Ordner /statistik in welchem ebenfalls eine .html liegt. Was muss ich in der .htaccess schreiben das diese Datei nicht auf index.php geleitet wird bzw. ist das über die .htaccess im Document Root des Webverzeichniss überhaut möglich?

    Genauso wie sich diese Regel in das Unterverzeichnis vererbt, wird sich auch eine Ausschlussklausel weitervererben. Üblicherweise möchte man, dass alle vorhandenen Dateien direkt ausgeliefert werden und nur nicht Vorhandenes umgeschrieben wird.

    RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ...

    Wenn du wirklich nur die eine Datei ausschließen möchtest, dann kannst du mit einer ähnlichen RewriteCond den angefragten Request-Filename auf den Namen der Statistik-HTML-Datei prüfen.

    Lo!

    1. RewriteEngine on
      RewriteRule ^(.*).html$ index.php
      leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei.

      Nein, das arbeitet fehlerhaft,

      ?? http://www.modrewrite.de/mod-rewrite/beispiele/php-wird-html/

      1. Hi,

        Nein, das arbeitet fehlerhaft,
        ?? http://www.modrewrite.de/mod-rewrite/beispiele/php-wird-html/

        die Autoren des von Dir genannten Artikels freuen sich sicherlich, wenn Du sie auf ihren Fehler hinweist.

        Cheatah

        --
        X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
        X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
        X-Will-Answer-Email: No
        X-Please-Search-Archive-First: Absolutely Yes
        1. Ach so, da denkt man nun das es doch genau da richtig sein müsste....

          Nun weiss ich aber immer noch nicht was ich machen muss damit es im Ordner /statistik auf der dort liegenden index.html nicht greift. Ich habe leider absolut keine Ahnung von reulären Ausdrücken.

          Gruß Rainer

    2. hi,

      RewriteEngine on
      RewriteRule ^(.*).html$ index.php
      leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei.

      Nein, das arbeitet fehlerhaft, nur dass du den Fehlerfall anscheinend nicht ausreichend getestet hast. Der Punkt ist ein Sonderzeichen. Er kann nicht einmal für ein beliebiges Zeichen stehen und einmal für sich selbst, ohne dass konkret gekennzeichnet ist, was genau gewünscht ist. In deinem Fall steht der zweite Punkt ebenfalls für ein beliebiges Zeichen. Ihn auf einen Punkt einzuschränken verlangt, ihn mit einem vorangehenden Backslash zu notieren.

      Sei sogut und schreib mal auf, wie das richtig lauten muss.

      Hotti

      1. Du meintest sicher dedlfix aber ioch habe es halt jetzt mal so eingesetzt:

        RewriteRule ^(.*).html$ index.php

        So funktioniert es auch. Hier nochmal komplett:

        RewriteEngine on
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*).html$ index.php

        und _so_ wird im Ordner /statistik die Datei index.html auch in Ruhe gelassen. Ob das nun von der Syntax her richtig ist weiss ich nicht.

        Gruß Rainer

        1. Hi!

          Du meintest sicher dedlfix aber ioch habe es halt jetzt mal so eingesetzt:
          RewriteRule ^(.*).html$ index.php

          So ist's richtig. Jetzt steht der Punkt für sich selbst.

          RewriteEngine on
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteRule ^(.*).html$ index.php
          und _so_ wird im Ordner /statistik die Datei index.html auch in Ruhe gelassen. Ob das nun von der Syntax her richtig ist weiss ich nicht.

          Zumindest werden damit alle real existierenden Dateien ausgenommen. Das ist nicht ganz das, was du eigentlich als Wunsch formuliert hast, denn da sprachst du nur von einer und nicht allen Dateien, aber ich denke, dass der jetzige Zustand ebenfalls mindestens zufriedenstellend ist.

          Lo!

      2. Hi!

        RewriteRule ^(.*).html$ index.php
        leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei.
        Nein, das arbeitet fehlerhaft, nur dass du den Fehlerfall anscheinend nicht ausreichend getestet hast. Der Punkt ist ein Sonderzeichen. Er kann nicht einmal für ein beliebiges Zeichen stehen und einmal für sich selbst, ohne dass konkret gekennzeichnet ist, was genau gewünscht ist. In deinem Fall steht der zweite Punkt ebenfalls für ein beliebiges Zeichen. Ihn auf einen Punkt einzuschränken verlangt, ihn mit einem vorangehenden Backslash zu notieren.
        Sei sogut und schreib mal auf, wie das richtig lauten muss.

        Sei so gut und trainiere dein Leseverständnis oder sag mir, was an meiner Aussage, den zweiten Punkt - oder allgemein alle Punkte, die für sich selbst stehen sollen - mit einem vorangehenden Backslash zu notieren, so unverständlich ist, dass man dafür noch ein explizites Beispiel benötigt?

        Lo!

        1. hi,

          RewriteRule ^(.*).html$ index.php
          leite ich alle Anfragen mit *.html an die index.php. Das funktioniert einwandfrei.
          Nein, das arbeitet fehlerhaft, nur dass du den Fehlerfall anscheinend nicht ausreichend getestet hast. Der Punkt ist ein Sonderzeichen. Er kann nicht einmal für ein beliebiges Zeichen stehen und einmal für sich selbst, ohne dass konkret gekennzeichnet ist, was genau gewünscht ist. In deinem Fall steht der zweite Punkt ebenfalls für ein beliebiges Zeichen. Ihn auf einen Punkt einzuschränken verlangt, ihn mit einem vorangehenden Backslash zu notieren.
          Sei sogut und schreib mal auf, wie das richtig lauten muss.

          Sei so gut und trainiere dein Leseverständnis oder sag mir, was an meiner Aussage, den zweiten Punkt - oder allgemein alle Punkte, die für sich selbst stehen sollen - mit einem vorangehenden Backslash zu notieren, so unverständlich ist, dass man dafür noch ein explizites Beispiel benötigt?

          Ich brauche das Beispiel, damit ich den Unterschied besser erkennen kann. Zum Testen habe ich Perl genommen:

            
          my $s = 'foo.html';  
            
          $s =~ /^(.*).html$/;  
          print "$&\n"; # foo.html  
          $s =~ /^(.*)\.html$/;  
          print "$&\n"; # same as above  
          
          

          $& (alias $MATCH) beeinhaltet in beiden Fällen 'foo.html'. Wo ist der Unterschied, oder anders gefragt: Warum führt das Nicht-Maskieren des zweiten Punkts zu einem Fehler?

          Hotti

          1. Hi!

            my $s = 'foo.html';

            $s =~ /^(.).html$/;
            print "$&\n"; # foo.html
            $s =~ /^(.
            ).html$/;
            print "$&\n"; # same as above

            
            >   
            > $& (alias $MATCH) beeinhaltet in beiden Fällen 'foo.html'. Wo ist der Unterschied, oder anders gefragt: Warum führt das Nicht-Maskieren des zweiten Punkts zu einem Fehler?  
              
            Die Aufgabenstellung war, dass alle Dateien, die auf .html enden, berücksichtigt werden. Es werden aber auch Dateien mit {beliebiges Zeichen}html berücksichtigt. Das ist der Fehler. Man muss nicht nur die gewünschten Fälle berücksichtigen und sich freuen, wenn die gehen, sondern man muss auch die ungewünschten wirksam ausschließen.  
              
            Deine beiden Fälle passen, weil im ersten Muster der . in foo.html ebenfalls in die Kategorie "beliebiges Zeichen" fällt und im zweiten Fall exakt passt. Das erste Muster lässt auch foo-html zu, das zweite nicht - und damit erfüllt das erste die Anforderung nicht mehr vollständig.  
              
              
            Lo!
            
            1. hi,

              my $s = 'foo.html';

              $s =~ /^(.).html$/;
              print "$&\n"; # foo.html
              $s =~ /^(.
              ).html$/;
              print "$&\n"; # same as above

              
              > >   
              > > $& (alias $MATCH) beeinhaltet in beiden Fällen 'foo.html'. Wo ist der Unterschied, oder anders gefragt: Warum führt das Nicht-Maskieren des zweiten Punkts zu einem Fehler?  
              >   
              > Die Aufgabenstellung war, dass alle Dateien, die auf .html enden, berücksichtigt werden.  
                
              Passt in beiden Fällen. Siehe Ankersetzung am Ende.  
                
              
              > Deine beiden Fälle passen, weil im ersten Muster der . in foo.html ebenfalls in die Kategorie "beliebiges Zeichen" fällt und im zweiten Fall exakt passt. Das erste Muster lässt auch foo-html zu, das zweite nicht - und damit erfüllt das erste die Anforderung nicht mehr vollständig.  
                
              ~~~perl
                
              my $s = 'foo-html';  
                
              $s =~ /^(.*).html$/;  
              print "$1 $&\n";  
              $s =~ /^(.*)\.html$/;  
              print "$1 $&\n";  
                
              # Ausgabe  
              # foo foo-html  
              # foo foo-html  
              
              

              Passt also auch in beiden Fällen. Warum ist /^(.*).html$/ bezüglich der Aufgabenstellung falsch?

              Hotti

              1. Hi!

                Deine beiden Fälle passen, weil im ersten Muster der . in foo.html ebenfalls in die Kategorie "beliebiges Zeichen" fällt und im zweiten Fall exakt passt. Das erste Muster lässt auch foo-html zu, das zweite nicht - und damit erfüllt das erste die Anforderung nicht mehr vollständig.

                my $s = 'foo-html';

                $s =~ /^(.).html$/;
                print "$1 $&\n";
                $s =~ /^(.
                ).html$/;
                print "$1 $&\n";

                Ausgabe

                foo foo-html

                foo foo-html

                
                >   
                > Passt also auch in beiden Fällen. Warum ist /^(.\*).html$/ bezüglich der Aufgabenstellung falsch?  
                  
                Ich weiß nicht, was in deiner Teststellung falsch ist. Das zweite Muster verlangt explizit einen . und darf bei - nicht matchen. Und gemäß Aufgabenstellung wurde explizit .html gewünscht und implizit darf dann -html nicht passen.  
                  
                ~~~php
                <?php  
                $s = 'foo.html';  
                var_dump(preg_match('/^(.*).html$/', $s)); // int(1)  
                var_dump(preg_match('/^(.*)\.html$/', $s)); // int(1)  
                  
                $s = 'foo-html';  
                var_dump(preg_match('/^(.*).html$/', $s)); // int(1)  
                var_dump(preg_match('/^(.*)\.html$/', $s)); // int(0)
                

                Das Ergebnis von preg_match() ist die Anzahl, wie oft das Muster passt. Der zweite und der vierte Fall bringen beide das richtige Ergebnis: passt und passt nicht.

                Lo!

                1. hi,

                  Ich weiß nicht, was in deiner Teststellung falsch ist.

                  Die Teststellung selbst:

                    
                  my $s = 'foo-html';  
                    
                  $s =~ /^(.*).html$/;  
                  print "$1 $&\n";  
                  $s =~ /^(.*)\.html$/;  
                  print "$1 $&\n";  
                  
                  

                  Das Zweite 'print' gibt den MATCH der ersten Expression einfach noch_einmal aus. Die Zweite Expression matcht gar nicht.

                  Danke Dir!!!!

                  Hotti

              2. [...] Passt also auch in beiden Fällen.

                Nein. Deine Erwartungshaltung zu $1 ist falsch:

                  
                my $s = 'foo-html';  
                if ($s =~ /^(.*).html$/) {  
                	print "1|$1 $&\n";  
                }	  
                if ($s =~ /^(.*)\.html$/) {  
                	print "2|$1 $&\n";  
                }  
                
                

                Warum ist /^(.*).html$/ bezüglich der Aufgabenstellung falsch?

                Weil hier der zweite Punkt anlog dem ersten ein Platzhalter ist.

          2. Hallo,

            Ich brauche das Beispiel, damit ich den Unterschied besser erkennen kann.

            das erinnert mich an einen Kollegen von früher. Der war in der Elektrowerkstatt tätig, machte aber auch bei der Bestückung von Leiterplatten und ähnlichen "feinen" Lötarbeiten eine gute Figur. Wenn ich dem eine Skizze hingelegt und ihn gebeten habe, mir nach diesem Schema ein Adapterkabel zu "stricken", hat er meist ein wenig hilflos geguckt und dann in breitestem Schwäbisch gefragt: "Hosch do net a Muschter zum Nachbaua?"
            Ein existierendes Muster nachbauen ... das machte er dann aber absolut zuverlässig. :-)

            $& (alias $MATCH) beeinhaltet in beiden Fällen 'foo.html'. Wo ist der Unterschied, oder anders gefragt: Warum führt das Nicht-Maskieren des zweiten Punkts zu einem Fehler?

            Weil der Ausdruck dann nicht nur auf index.html oder home.html passt, sondern beispielsweise auch auf somehtml. Mit anderen Worten: Das Zeichen vor "html" wäre beliebig, und nicht unbedingt ein Punkt.

            Ciao,
             Martin

            --
            Die letzten Worte der Challenger-Crew:
            Lasst doch mal die Frau ans Steuer!
            Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
            1. Weil der Ausdruck dann nicht nur auf index.html oder home.html passt, sondern beispielsweise auch auf somehtml. Mit anderen Worten: Das Zeichen vor "html" wäre beliebig, und nicht unbedingt ein Punkt.

              Ja richtig, aber durch das $ nach dem .html muss .html am Ende des Dateinamens stehen. Und welche Datei heißt den selfhtml ohne Dateiendung? Wahrscheinlich sehr wenige. Deshalb ist der Backslash wie ich finde nicht zwingend.

              Gruß
              T-Rex

              1. Hi!

                Ja richtig, aber durch das $ nach dem .html muss .html am Ende des Dateinamens stehen. Und welche Datei heißt den selfhtml ohne Dateiendung? Wahrscheinlich sehr wenige. Deshalb ist der Backslash wie ich finde nicht zwingend.

                Dann kannst du aber auch gleich den Punkt ganz weglassen. Er ist in diesem Fall dann nämlich sinnlos. (Vorausgesetzt dass wie im OP der gruppierte Ausdruck "(.*)" nicht weiter verwendet wird. Dann sind auch die Klammern überflüssig, das ^ am Anfang sowieso.)

                Lo!

                1. Dann kannst du aber auch gleich den Punkt ganz weglassen. Er ist in diesem Fall dann nämlich sinnlos. (Vorausgesetzt dass wie im OP der gruppierte Ausdruck "(.*)" nicht weiter verwendet wird. Dann sind auch die Klammern überflüssig, das ^ am Anfang sowieso.)

                  So gesehen eigentlich schon, da hast du recht.
                  Und schon ist die htaccess Zeile total einfach :D.

                  Gruß
                  T-Rex