manni: mod_rewrite - forcetype - herausfinden, was geht

Hallo,

ich möchte schöne URLs innerhalb eines Projektes entweder mit mod_rewrite, .htaccess-forcetype oder zur Not halt die GET-Parameter stehen lassen.

Dafür möchte ich das Konfigurationsskript herausfinden lassen, was geht und was nicht.

Wie kann ich testen, ob mod_rewrite möglich ist?
Wenn und ich mit php die Datei nicht schreiben darf wegen den Rechten gebe ich dem User einfach eventuell vorhandene .htaccess mit der angehängten Regel aus, die er dann selber schreiben muss.

Kann ich herausfinden, ob forcetype erlaubt ist?
Wenn ja gebe ich halt auch wieder entsprechende htaccess Zeilen aus, falls nicht direkt die .htaccess geschrieben werden kann.

Gruß

  1. Hallo,

    um das mal anders auszudrücken.

    Innerhalb eines Auftrittes sollen die URLs mit einer der folgenden 3 Methoden "verschönert" werden:

    • mod_reqrite: domain.de/de/kontakt/senden wird auf domain.de/de.php?lv1=kontakt&lv2=senden weitergeleitet (hierfür fehlt mir noch eine wirklich elegante mod_reqrite-Regel)
    • forcetype: die Dateien de, en, etc. werden per .htaccess-forcetype als PHP verarbeitet und lesen die Parameter domain.de/de/kontakt/senden entsprechend aus
    • domain.de.php/kontakt/senden: zur Not wird der Query-String eben so geform und muss entsprechend durch php ausgelesen werden.

    Nun habe ich dazu folgende Fragen:

    • Ich möchte eine Art "Schau was dein Server kann" Funktion mit einem PHP-Skript realisieren, dass sich dann jenachdem, was am Server möglich ist der Reihe nach für mod_reqrite, forcetype oder die letzte Lösung ausspricht.
      Doch wie kann ich mit PHP herausfinden, ob mod_reqrite tut? Und wie, ob forcetype erlaubt ist?
    • Demnächst werde ich eine Seite haben, die nicht multilingual ist, dadurch ergeben sich kleinere Probleme:
          - Die frocetypemethode werde ich halt einfach auch eine allgemeine nichtssagende Datei "www" legen, da werde ich keine andere Möglichkeit haben.
          - genauso die letzte Lösung werde ich eben auf eine Nichtssagende www.php/ legen
          - doch wie löse ich das ganze für mod_rewrite? ich meine da könnte ich ja auf den ersten part, der für die Sprache zuständig war völlig verzichten. Aber wie leite ich das dann am besten wohin? Einfach auch auf die existierende nichtssagende www.php müsste doch gehen. DOch die erkennt ja dann nicht, ob sie jetzt GET-Parameter auslesen muss (durch mod_rewrite) oder ob sie den String selber verarbeiten muss kontakt/senden

    Ich hoffe das ich etwas verständlicher und nicht zu lang, wo mein bescheidenes Problemchen liegt beim Denken.

    Grüßle

    1. ...hmhm...hm...

    2. echo $begrüßung;

      • mod_reqrite: domain.de/de/kontakt/senden wird auf domain.de/de.php?lv1=kontakt&lv2=senden weitergeleitet (hierfür fehlt mir noch eine wirklich elegante mod_reqrite-Regel)

      Zumindest dafür habe ich eine Antwort:

      RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule .* de.php [QSA]

      Existierende Dateien und Verzeichnise ignorieren, ansonsten alles auf die de.php umschreiben (oder auch woandershin). kontakt, senden und was sonst noch so dranhängt kann man aus $_SERVER['REQUEST_URI'] ermitteln. Mit trim($_..., '/') entledigt man sich unnötiger Schrägstriche. Und explode('/', ...) separiert die Teile.

      • Ich möchte eine Art "Schau was dein Server kann" Funktion mit einem PHP-Skript realisieren, dass sich dann jenachdem, was am Server möglich ist der Reihe nach für mod_reqrite, forcetype oder die letzte Lösung ausspricht.

      Die Frage nach mod_rewrite ist lösbar, wenn PHP als Apache-Modul eingebunden ist. Mit apache_get_modules() kannst du alle geladenen Module ermitteln. Ob du mod_rewrite-Direktiven tatsächlich nutzen kannst steht auf einem anderen Blatt. Auch die anderen Direktiven geben nicht preis, ob sie genutzt werden können oder nicht.

      Wenn du Schreibzugriff auf ein Verzeichnis hast, kannst du zumindest dort dir eine eigene .htaccess anlegen und dann http-Zugriffe darauf abfeuern und das Ergebnis auswerten.

      echo "$verabschiedung $name";

      1. Hallo,

        vielen Dank für deine Antwort.

        Zumindest dafür habe ich eine Antwort:

        RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule .* de.php [QSA]

        Existierende Dateien und Verzeichnise ignorieren, ansonsten alles auf die de.php umschreiben (oder auch woandershin). kontakt, senden und was sonst noch so dranhängt kann man aus $_SERVER['REQUEST_URI'] ermitteln. Mit trim($_..., '/') entledigt man sich unnötiger Schrägstriche. Und explode('/', ...) separiert die Teile.

        Ich würde aber gerne abhängig davon, welche Sprache gesetzt ist auf die jeweilige Seite leiten:

        • domain.de/de/kontakt auf de.php
        • domain.de/en/kontakt auf en.php

        Des Weiteren ist für mich die Frage, wenn ich wirklich Verzeichnisse etc. ignoriere, was passiert dann, wenn ich z.B. ein Bild <img src="domain.de/bilder/bild.jpg"> einbinde? Dies wird ja dann auch weitergeleitet?

        Kann ich auch für Projekte, bei denen nur eine Sprache exisiert sowas wie domain.de/kontakt abfangen und auf index.php/kontakt weiterleiten?

        Wenn du Schreibzugriff auf ein Verzeichnis hast, kannst du zumindest dort dir eine eigene .htaccess anlegen und dann http-Zugriffe darauf abfeuern und das Ergebnis auswerten.

        Danke für den Denkanstoß. Schreibzugriff habe ich bei der "Installation&Konfiguration" auf jedenfall, dann könnte ich zuerst ein mod_rewrite-Test falls der Schiefgeht einen forcetype Test schreiben.
        Einzige frage dazu, was eignet sich am besten um "http-Zugriffe" mit PHP abzufeuern und zu prüfen ob ich einen 404 habe?

        Wegen dem Handling von Seiten, die eventuell selber wieder Parameter erfordern: Was ist da gängige Praxis? domain.de/kontakt/senden/blabla=true

        Und dann mit php einfach die ersten an / gesplitteten Elemente als Seitenpfad registrieren und sobald das erste Element mit = auftaucht entsprechende GET setzen?
        Wie würde ich dann ein GET-Formular schön umleiten? Von sich aus würde es ja ertsmal einfach domain.de/kontakt/senden?blabla=true erzeugen?

        Vielen Dank für deine Antwort

        1. echo $begrüßung;

          RewriteCond %{REQUEST_FILENAME} !-f
            RewriteCond %{REQUEST_FILENAME} !-d
            RewriteRule .* de.php [QSA]
          Ich würde aber gerne abhängig davon, welche Sprache gesetzt ist auf die jeweilige Seite leiten:

          • domain.de/de/kontakt auf de.php
          • domain.de/en/kontakt auf en.php

          Auch das ist kein Problem

          RewriteRule ^(.*)/.*$ $1.php [QSA]

          Des Weiteren ist für mich die Frage, wenn ich wirklich Verzeichnisse etc. ignoriere, was passiert dann, wenn ich z.B. ein Bild <img src="domain.de/bilder/bild.jpg"> einbinde? Dies wird ja dann auch weitergeleitet?

          Da die Regel bei existierenden Dateien aufgrund der RewriteConds nicht zutrifft, werden diese normal ausgeliefert.

          Kann ich auch für Projekte, bei denen nur eine Sprache exisiert sowas wie domain.de/kontakt abfangen und auf index.php/kontakt weiterleiten?

          Natürlich. Gleiche Regeln wie oben, nur index statt de.

          Einzige frage dazu, was eignet sich am besten um "http-Zugriffe" mit PHP abzufeuern und zu prüfen ob ich einen 404 habe?

          Eine fertige HTTP-Request- oder -Client-Klasse, die sich um den ganzen "Kram" kümmert, die getestet ist, und der du nur noch die URL übergibst und im Gegenzug Response-Code und Inhalt übergeben bekommst. Gibt's beispielsweise bei PEAR. Ansonsten gibt es auch noch curl, aber ohne Vorhandenseinsgarantie.

          Wegen dem Handling von Seiten, die eventuell selber wieder Parameter erfordern: Was ist da gängige Praxis? domain.de/kontakt/senden/blabla=true

          Der eingangs genannte Vorschlag mit Auswertung des REQUEST_URI statt der oft zu sehenden Anhängerei der Pfadbestandteile als Query-Parameter hat zwar ein gegenüber dem Zugriff auf das $_GET-Array etwas aufwendigeres Auswerten zur Folge, lässt aber ebendieses $_GET-Array komplett für echte Query-Parameter unangetastet.

          Ein GET-Formular, das action="/kontakt/senden" hat, erzeugt einen Request nach /kontakt/senden?param=value.

          Ich seh gerade, dass bei vor Auswertung des REQUEST_URI noch der Querystring abgeschnitten werden muss. Diese Daten stehen da ja auch drin. Das hatte ich beim ersten Antworten nicht beachtet.

          Und dann mit php einfach die ersten an / gesplitteten Elemente als Seitenpfad registrieren und sobald das erste Element mit = auftaucht entsprechende GET setzen?

          GET und POST funktionieren wie üblich. Sie werden von meinem Vorschlag nicht beinträchtigt.

          Wie würde ich dann ein GET-Formular schön umleiten? Von sich aus würde es ja ertsmal einfach domain.de/kontakt/senden?blabla=true erzeugen?

          Wohin umleiten? Eine RewriteRule interessiert sich nicht für den Querystring. Sie leitet anhand des Pfades um. Das [QSA] sorgt dann dafür, dass der Querystring nicht verloren geht.

          Bitte für Beispiele die dafür vorgesehenen Domainnamen verwenden, nicht welche, die irgendwem gehören könnten.

          echo "$verabschiedung $name";

          1. Hallo,

            wieder vielen vielen Dank.

            Einzige frage dazu, was eignet sich am besten um "http-Zugriffe" mit PHP abzufeuern und zu prüfen ob ich einen 404 habe?

            Eine fertige HTTP-Request- oder -Client-Klasse, die sich um den ganzen "Kram" kümmert, die getestet ist, und der du nur noch die URL übergibst und im Gegenzug Response-Code und Inhalt übergeben bekommst. Gibt's beispielsweise bei PEAR. Ansonsten gibt es auch noch curl, aber ohne Vorhandenseinsgarantie.

            Oh das hat mein Kumpel leider alles nicht zur Verfügung. Dann bleibl wohl nur fsockopen?

            Wie würde ich dann ein GET-Formular schön umleiten? Von sich aus würde es ja ertsmal einfach domain.de/kontakt/senden?blabla=true erzeugen?

            Wohin umleiten? Eine RewriteRule interessiert sich nicht für den Querystring. Sie leitet anhand des Pfades um. Das [QSA] sorgt dann dafür, dass der Querystring nicht verloren geht.

            Ich meinte das eher so, dass ich ja den ganzen Schnickschack hier expample.com/de/kontakt/senden mache um schöne URLs zu haben. Wenn ich jetzt unter example.com/de/tierfreundeev/forum ein Forum habe würde ja die Domain hintenraus wieder zu einem Kauderwelsch. Deswegen würde ich hier gerne die Methode den REQUEST_URI auszulesen ebenfalls nutzen.
            Deswegen dachte ich an example.com/de/tierfreundeec/forum/seite=1/beitrag=10/
            Dabei könnte ich beim auslesen überprüfen, ob das Element ein = enthält, ist das der Fall gehören die Folgenden Elemente als Parameter zur aktuellen Seite.

            Nur kann ich es ja nicht vermeiden, dass eben ein form mit action=get mir wieder sowas produziert example.com/de/tierfreunde/forum/newpost?bestaetigungscode=false
            Dafür wollte ich eventuell eine Lösung auch dieses dann entsprechend "umzuleiten" example.com/de/tierfreunde/forum/newpost/bestaetigungscode=false/

            Gruß und vielen vielen Dank nochmal

            1. echo $begrüßung;

              Eine fertige HTTP-Request- oder -Client-Klasse, die sich um den ganzen "Kram" kümmert, die getestet ist, und der du nur noch die URL übergibst und im Gegenzug Response-Code und Inhalt übergeben bekommst. Gibt's beispielsweise bei PEAR. Ansonsten gibt es auch noch curl, aber ohne Vorhandenseinsgarantie.
              Oh das hat mein Kumpel leider alles nicht zur Verfügung. Dann bleibl wohl nur fsockopen?

              PEAR sind im Grunde genommen nur PHP-Scripte zum inkludieren. Du kannst die benötigten PEAR-Dateien (muss ja nicht das Komplettpaket sein) einfach zu deinem Projekt hinzufügen. Es ist dann egal, ob da auf dem Server schon PEAR installiert ist oder auch nicht oder vielleicht in einer unpassenden Version.

              Ich meinte das eher so, dass ich ja den ganzen Schnickschack hier expample.com/de/kontakt/senden mache um schöne URLs zu haben. Wenn ich jetzt unter example.com/de/tierfreundeev/forum ein Forum habe würde ja die Domain hintenraus wieder zu einem Kauderwelsch. Deswegen würde ich hier gerne die Methode den REQUEST_URI auszulesen ebenfalls nutzen.

              Man kann es auch übertreiben. Wenn eine Seite immmer wieder den gleichen Inhalt produziert, den aber in Abhängigkeit der Parameter anders darstellt (z.B. anders sortiert), dann sind solche Parameter meiner Meinung nach kein "Verstoß gegen ansprechende URLs".

              Deswegen dachte ich an example.com/de/tierfreundeec/forum/seite=1/beitrag=10/

              Das kannst du auch als example.com/de/tierfreunde_ev/forum/1/10/ notieren. Da du solche URLs ja nicht aus Formulardaten erhältst, sondern sie selbst zusammensetzt, weißt du ja, dass an Position 4 die Seite und an Position Stelle 5 der Beitrag steht. Noch besser wäre es, wenn du nicht solche Zahlen verwendetest sondern sprechende Bezeichnungen: example.com/de/tierfreunde_ev/forum/mein_mammut_macht_mist/

              Nur kann ich es ja nicht vermeiden, dass eben ein form mit action=get mir wieder sowas produziert example.com/de/tierfreunde/forum/newpost?bestaetigungscode=false
              Dafür wollte ich eventuell eine Lösung auch dieses dann entsprechend "umzuleiten" example.com/de/tierfreunde/forum/newpost/bestaetigungscode=false/

              Tät ich lassen. Es gibt bessere Alternativen als die Umleititis.

              Im Falle von "newpost/bestaetigungscode" scheint es sich mir um eine Geschichte zu handeln, die man besser nicht per GET aufrufen lassen möchte. Sonst kommt der erstbeste Linkverfolger (Suchmaschine) daher und ändert womöglich Daten allein durch Crawlen deiner Seite.

              echo "$verabschiedung $name";

    3. Hallo Manni,

      • mod_reqrite
      • forcetype
      • domain.de.php/kontakt/senden

      es kann so gar noch schlimmer kommen, dass Dir die letzte Möglichkeit mit der Direktive AcceptPathInfo genommen wird, wenn die anderen Möglichkeiten ausfallen. (Das sei deshalb angemerkt, damit auch dafür in einer etwaigen Programmierung (z. B.) eines setup-scripts weitere Ausweichmöglichkeiten geschaffen werden.)

      • Ich möchte eine Art "Schau was dein Server kann" Funktion mit einem PHP-Skript realisieren, dass sich dann jenachdem, was am Server möglich ist der Reihe nach für mod_reqrite, forcetype oder die letzte Lösung ausspricht.

      Wie dedlfix schon bemerkte, sieht es bei einem apache-handler (PHP-Modul) noch recht günstig aus herauszufinden, welche Module der Apache bereithält. Nur ist es damit _alleine_ nicht getan. [Link:http://httpd.apache.org/docs/2.2/mod/core.html#allowoverride@title=AllowOverride] kann Dir hier gehörig in die Suppe spucken, sodass die Module zwar verfügbar sind, jedoch nicht konfiguriert werden können. (Das mag nicht nur absurd klingen, denn es ist auch absurd, aber es gibt tatsächlich solche Provider mit solchen restriktiven Konfigurationen, die die Module dennoch einbinden. ^,-) Um mit Deinem "Möglichkeitstest"-script portierbar zu sein und der vorwiegenden Nutzung ebenso gerecht zu werden, solltest Du von vornherein davon ausgehen, dass PHP über (Fast)CGI vom Server angesprochen wird.

      Erstelle Dir also ein Script, was ein Verzeichnis innerhalb des Webs erstellt, darin eine Datei (z. B. index.txt, Inhaltsvariante: "<?php phpinfo();?>) und eine Konfigurationsdatei (.htaccess) ablegt. In der .htaccess legst Du in nacheinander folgenden Testreihen unterschiedliche Konfigurationen ab (1) und greifst via HTTP von selben script darauf zu. Ein Testkonfiguration könne beispielsweise so aussehen:

        
      RewriteEngine on  
      RewriteRule   \.txt$ - [type=application/x-httpd-php]  
        
      # bei Fehlschlag nächster Versuch mit  
        
      ForceType application/x-httpd-php  
      
      

      Ist mod_rewrite nicht installiert, antwortet der Server mit Status 500. Dies kann mit fopen('http://do.main/m-test.php.dir/index.txt','r') und anschließendem resourcen Test via stream_get_meta_data() überaus komfortabel geprüft werden. Wird die Konfigurationsdatei vom Server gar nicht gelesen, ist die Ausgabe (in meinem Beispiel) "<?php info(); ?>" andernfalls die HTML-formatierte Ausgabe der geparsten index.txt.

      Gruß aus Berlin!
      eddi

      --
      Hypochondrie vor Parodontitis? Nikotin beruhigt die Nerven davon!