Gerhard: Was bedeutet dies Zeilenfolge in der .htaccess?

Hallo,
kann mir jemand erklären, was die folgenden Zeilen bewirken?

RewriteCond %{REQUEST_URI} !php
RewriteRule ^(.*)$ %1index.php [E=MyAkt_Seite:index]
RewriteCond %{REQUEST_URI} .*\/(.*)\.php
RewriteRule ^(.*)$ - [E=MyAkt_Seite:%1]
Quelltext hier

Danke
Gerhard

  1. Hallo Gerhard,

    Lektüre zum Ausdrucken und unter's Kopfkissen legen. Ich lege Dir vor allem die Introduction an's Herz.

    RewriteCond gibt Regeln vor, unter denen eine nachfolgende RewriteRule zu beachten ist.

    In deinem Beispiel gibt's zwei RewriteRules, jede mit einer RewriteCond.

    "Quelltext hier" ist keine Apache Direktive, diese Zeile dürfte in einer .htaccess nichts zu suchen haben.

    RewriteCond hat zwei bis drei Parameter.

    Parameter 1: Der zu testende String. Bei Dir in beiden Fällen %{REQUEST_URI}. Das bezeichnet den Inhalt der Servervariablen REQUEST_URI, das ist das, was der Browser vom Server per HTTP anfordert (also alles ab dem / Zeichen, was hinter dem Domain-Namen steht).

    Parameter 2: Das Muster, das auf den String passen soll.

    Das Ausrufezeichen vorneweg ist ein "Nicht", die erste RewriteCond trifft also zu, wenn die URI nicht die Zeichenkette "php" enthält. Ganz schön leichtsinnig, es würde dazu führen, dass eine URI wie /php-beispiele/ von der Regel abgewiesen wird.

    Die zweite RewriteCond hat eine etwas komplexere Regex, die auf URIs wie dings/bums.php zutrifft. Aber auch hier ist wieder Vorsicht geboten, die Regex endet nicht auf $ (was dem Ende des Teststrings entsprechen würde) und deshalb würde sie auch auf sample/test.phpdemo/hugo.png zutreffen! Die Regex zeigt darüber hinaus, dass der Autor seinen Kontext nicht versteht. Sie setzt nämlich ein Escape-Backslash vor das / Zeichen, was aber in einer Regex nur dann nötig ist, wenn man sie klassisch mit / Zeichen als Begrenzungszeichen notiert (was in einer .htaccess-Datei nicht passiert).

    Ich kann Dir hier nicht alles über Regexe erklären. Unser Wiki hat hier eine Einstiegsseite dazu mit Links, und etwas mehr Infos zu Regexen in JavaScript. JavaScript-Regex und die vom Apache verwendeten PCRE-Regex sind ähnlich, aber nicht identisch. Die Apache Doku verlinkt für PCRE-Regex hierher, eine gut gepflegte Spielwiese gibt's hier.

    Die RewriteRule ist dann wieder ein Suchen und Ersetzen. Der Suchstring ist in beiden Fällen ^(.*)$ - was das gleiche sein dürfte wie %{REQUEST_URI}. Die Klammern in der Regex bilden darüber hinaus eine Match-Gruppe, auf die man im Ersetzungsstring mit $1 zugreifen könnte. Tut das Beispiel aber nicht, es verwendet %1, was sich auf die Matches von RewriteCond bezieht.

    Im Falle der ersten RewriteRule dürfte das ein Schlag ins Wasser sein, weil sie ja dann zutrifft, wenn es keinen Match gibt. Ich habe keinen Spiel-Apache da, aber es gibt eine htaccess Spielwiese und die besagt, dass dann einfach %1 stehen bleibt. Vermutlich muss man hier %{REQUEST_URI}index.php einsetzen, oder besser noch, die Ersetzung bleiben lassen und die Eigenschaft von mod_dir ausnutzen, bei Abruf eines Verzeichnisses eine Indexdatei zu liefern. So:

    DirectoryIndex index.php
    

    Im Fall der zweiten RewriteRule wird kein Schaden angerichtet, weil der Ersetzungsstring "-" ist. Das bedeutet: "Nichts ersetzen".

    In beiden Fällen wird aber noch eine Option gesetzt: E. Das steht für Environment, d.h. im Server wird eine Umgebungsvariable MyAkt_Seite gesetzt. Im Fall der ersten Cond/Rule Gruppe auf index, bei der zweiten Cond/Rule Gruppe auf %1, das ist die erste Matchgruppe der Regex der RewriteCond. Also der Name der PHP Datei, ohne das PHP und ohne den Pfad.

    Als Nichtindianer glaube ich etliche Stellen zu sehen, die falsch oder unvollständig behandelt werden. Aber das kann auch an meinem Halbwissen liegen…

    Aus meiner Sicht sollte im ersten Fall geprüft werden, ob die URL ein Verzeichnis darstellt, mit RewriteCond %{REQUEST_URI} -d, statt nach PHP zu suchen. %{REQUEST_URI} ist vermutlich auch nicht nötig, %{REQUEST_FILENAME} sollte bei einer .htaccess Datei reichen.

    Rolf

    --
    sumpsi - posui - obstruxi