ModRewrite für eigene Webseite

  • ch möchte Link Umschreibungen für ein eigenes Projekt erstellen. Folgende Bedingungen liegen vor:


    Szenario lokaler Webserver:

    localhost/projektname/index.php?seite=irgendwas

    Ziel: localhost/projektname/irgendwas


    Szenario Webserver

    example.com/index.php?seite=irgendwas

    Ziel: example.com/irgendwas


    Also mein Problem ist, dass es ein Unterverzeichnis mehr gibt. Also soll die RewriteRule(s) unabhängig von eventuellen Unterverzeichnissen sein.


    Auf dem lokalen Server habe ich bis jetzt folgende Regeln die aber nur mit dem lokalen Unterordner funktioniert:


    Code: .htaccess

    1. RewriteEngine On
    2. RewriteRule ^([a-zA-Z0-9]+)$ /projektname/index.php?seite=$1 [L]
  • Muss ich hier eine eigene Regel erstellen, wenn ich kein Verzeichnis habe? Oder kann man das in eine Regel packen?

    Genau das macht #2. Lies das verlinkte Tutorial, dann hilft Dir der Code auch sicher weiter.


    Beispiel:

    Eingabe in Browser-Adressleiste: https://www.example.com/irgendwas

    Mit einer .htaccess wie in #2, wird die Anfrage wie gewünscht auf die index.php geleitet, da es kein Verzeichnis irgendwas gibt.


    Da ich nicht wissen kann, wo Du den Inhalt der Seite irgendwas am Ende abgelegt hast, gehe ich mal exemplarisch davon aus, dass es eine Verzeichnisstruktur /views/pages/ gibt, wo die entsprechenden Inhalte als .html-Dateien vorliegen.


    Mit der Annahme könnte ich dann in der index.php nach beispielhaftem Prinzip einfach den Dateiinhalt laden und ausgeben:

    PHP
    1. // creating path to content
    2. $sContentPath = __DIR__ . '/views/pages/' . trim( $_SERVER['REQUEST_URI'], '/' ) . '.html';
    3. // load content and send to output channel if file exists
    4. if ( file_exists($sContentPath) )
    5. echo file_get_contents( $sContentPath );


    Ist lt. meinem Verständnis genau das, was Du benötigst und die übliche Vorgehensweise. Ansonsten musst Du Dein Anliegen nochmal genauer erklären.

    Und das steht alles im Link aus #2.

  • Ich finde nicht, dassdas System unflexibel wird. Alles was nach der Domain ist, kann als Paramter der index.php genutzt werden. Und ich bin einmal in htaccess und muss nicht mit einer Mischung aus beiden Arbeiten.
    Egal ist es mir nicht. Denn ich habe auch gefragt, wieso mein RewriteBase nicht funktioniert. Was ich gefunden habe, dient lediglich als Zwischenstand, um die Leser auf den aktuellen Stand zu bringen wo ich mich gedanklich befinde.

  • Dein Prinzip unterscheidet sich zielführend wenig von der richtigen Variante, nur dass Du wie gesagt sehr unflexibel bist.

    Unflexibel in der Hinsicht, dass Du bspw. nicht auf URLs á la example.com/rgendwas/nochwas eingehst. Das wäre zwar mit einer Anpassung des Pattern relativ einfach anpassbar, aber Du musst dafür die .htaccess bearbeiten, was nicht zielführend sein kann für Produktivsysteme.


    In Deiner index.php vermute ich mal eine Verarbeitung über $_GET, also tippe ich mal ganz stark darauf, dass die RewriteRule nur aus dem Grund mit dem Parameter seite arbeitet, weil Du meinst, dass Du nur so an den Parameter ran kommst. Tatsächlich sollte ( grad getestet, passt! ) das alles aber auch in $_SERVER['REQUEST_URI'] stehen.


    Warum also mit Parametern arbeiten, wenn alles was man braucht schon da ist?

    Das bezeichne ich als umständlich. Du magst das anders sehen, ist Dein Projekt, daher kann ich Dir nur sagen, wie man es richtig macht, aber das muss Dich nicht zwingen es nicht anders umständlicher umzusetzen.



    Zur Erklärung:

    Dein Code aus #5 mal als Vorlage kopiert

    Code
    1. RewriteEngine On
    2. RewriteRule ^([a-zA-Z0-9]+)$ %{SCRIPT_URL}?seite=$1 [L]

    kann ich auch kurz und knapp so schreiben, um alle URL-Varianten abzudecken ( %{SCRIPT_URL} der Einfachheit im flg. gegen index.php ausgetauscht ):

    Code
    1. RewriteEngine On
    2. RewriteRule ^(.*)$ index.php?seite=$1 [QSA][L]

    Wenn ich mich nun einfach auf den REQUEST_URI beziehe, kann ich das so umschreiben:

    Code
    1. RewriteEngine On
    2. RewriteRule ^.* index.php?seite=%{REQUEST_URI} [QSA][L]

    Nun kann man schon erahnen, dass in REQUEST_URI wohl der URI inkl. aller Parameter steckt und diese nicht extra übergeben werden muss.

    Also kann ich auch schreiben:

    Code
    1. RewriteEngine On
    2. RewriteRule ^.* index.php [QSA][L]

    ...und das führt uns schon in die Nähe des Post #2:

    Code
    1. RewriteEngine On
    2. RewriteRule ^ index.php [QSA][L]

    Was Dein Prinzip allerdings nicht berücksichtigt - egal, welche der bisher dargestellten Varianten Du nutzt - ist, dass alle Anfragen auf die index.php umgeleitet werden. Wenn Du Pech hast, landen diese Anfragen auch auf der index.php:

    HTML
    1. <img src="//example.com/bild.jpg">

    Um das zu umgehen, gibt man dem Webserver über sogenannte RewriteConditions bestimmte Regelkonditionen mit auf den Weg.

    Umgangssprachlich zusammengefasst, wären das folgende Konditionen: Gilt nur für nicht physikalisch existente Dateien oder Verzeichnisse.


    Die Kondition als Code müssen wir pro Kriterium setzen, also einmal für die Dateien: RewriteCond %{REQUEST_FILENAME} !-f und einmal für die Verzeichnisse: RewriteCond %{REQUEST_FILENAME} !-d.


    Wer jetzt aufgepasst hat, erkennt schnell, dass wir mit den beiden Zeilen und der letzten Version dieser Erklärung am Ende auf das Resultat aus #2 kommen:

    Code
    1. RewriteEngine On
    2. RewriteBase /
    3. RewriteCond %{REQUEST_FILENAME} !-f
    4. RewriteCond %{REQUEST_FILENAME} !-d
    5. RewriteRule ^ index.php [QSA,L]

    Bedeutet also im Grunde: Ist das angeforderte Ziel über das Dateisystem nicht lückenlos abbildbar, springe in die index.php. Darin wären Deine Fälle ebenso abgedeckt, wie jeder andere, reagieren tust Du in der index.php sowieso, Du nutzt Du halt nur z.Zt. noch $_GET, anstatt $_SERVER['REQUEST_URI'].

    Es kann sogar sein, dass auch alles automatisch in $_GET steht, das kann ich allerdings nur vermuten, da ich das kaum nutze.


    Du musst es aber natürlich nicht richtig machen, ich denke nur, dass Du relativ schnell Deinen Kram anpassen musst, wenn Du es nicht so machst.

  • Es gibt wie so oft im Leben auch mehrere Lösungen zum Ziel. Daher muss deine Lösung auch nicht die einzig wahre Lösung sein. Aber genau so stellst du diese hier hin.

    Schon einmal darüber nachgedacht, dass mir eine Ebene in der Tiefe reicht? Die Seitenstruktur, die ich habe, läuft bei mir schon viele Jahre. Wie immer beim Programmieren werden die Projekte immer weiter entwickelt. Die sind nicht in Stein gemeißelt. Daher kann ich durchaus eine htaccess später nocheinmal ändern.


    Eigentlich spielt es keine Rolle, da nur die Frage war, wie ich die Adressen umschreibe. Die dynamischen Adresse nutzte ich schon lange. Auch dass die index.php den Inhalt lädt, der per Parameter angefordert wird.

    In $_GET steht alles drin, was ich brauche: Diese Seite wo es hingehen soll. Wie gesagt, die Struktur ist schon viele Jahre bei mir so und ist auch erweiterbar. In $_SERVER['REQUEST_URI']  steht zusätzlich noch der Dateiname also in meinen Fall index.php . Die Information ist an der Stelle unnötig. Daher reicht $_GET Den Hinweis mit den nicht existierenden Verzeichnissen und Datein nehme ich auf.

    Mir ist nicht schlüssig, wieso ich bei der Linkumschreibung auch noch meinen PHP anpassen soll, wenn es die Linkumschreibung alleine kann. Was mir hier fehlt ist die richtige Syntax. Da es für bestehen Projekte sein soll, möchte ich erst einmal nicht in der PHP Änderungen vornehmen. Einzig die Link-Tags müssten angepasst werden.


    Nun eine konkrete Frage zum Post #1:

    Wenn ich ein Unterverzeichnis habe passt das mit RewriteBase /nicht mehr. Muss ich für jede Umgebung eine eigene htaccess haben? Oder kann man durch die Regeln nicht automatisch eine Datei auf beiden Umgebung benutzen?

  • Daher muss deine Lösung auch nicht die einzig wahre Lösung sein.

    Habe ich nie behauptet...


    Aber genau so stellst du diese hier hin.

    Nö, Du unterstellst mir, dass ich es so hinstelle...



    Schon einmal darüber nachgedacht, dass mir eine Ebene in der Tiefe reicht?

    Ja, hast Du denn gelesen, dass ich Dich auf kommende Situationen vorbereiten wollte:

    Scheint Dir aber egal zu sein, dann sehen wir uns halt wieder, wenn die URL Dich mit neuen Varianten verwöhnt...

    ...uuuuund ZACK, siehe da:

    Nun eine konkrete Frage zum Post #1:

    Wenn ich ein Unterverzeichnis habe passt das mit RewriteBase /nicht mehr. Muss ich für jede Umgebung eine eigene htaccess haben? Oder kann man durch die Regeln nicht automatisch eine Datei auf beiden Umgebung benutzen?

    Du hast immer noch nicht verstanden, dass die von mir gezeigte Lösung Dein Problem schon längst gelöst hätte...

    Na Du wirst hier sicher noch Lösungen bekommen, die Du für gut erachten wirst. Meine ist Dir ja scheinbar zu aufdringlich, das war nicht der Plan dahinter, eigentlich wollte ich nur helfen. Lösungen gibt es viele, ja das stimmt. Manche sind halt umständlich und tlw. sogar Humbug, aber es ist Dein Projekt, Du entscheidest allein, welche Lösung Du hernehmen möchtest.


    Viel Erfolg

    ;)

  • Zunächst: ich habe versucht hier keinen Streit aufkommen zu lassen. Vielleicht reden wir auch aneinander vorbei.

    Daher clr scr und nun von vorn:
    Ich habe deine Lösung bei mir nicht zum laufen bekommen. Daher ist die Frage für mich noch nicht gelöst.


    Ich habe mal geguckt, wie es Woltlab (dieses Forum) macht. Das habe ich dann auf mein Keyword angepasst und funktioniert auch.

    Code: .htaccess
    1. RewriteCond %{SCRIPT_FILENAME} !-d
    2. RewriteCond %{SCRIPT_FILENAME} !-f
    3. RewriteRule ^(.*)$ index.php?seite=$1 [L,QSA]

    Nach dem Motto "vom Leichten zum Schweren" konnen nun weiter gucken.

    nur du deinem example.com/irgendwas/nochwas du leitest alles auf die index.php weiter. Wo wertest du das dann aus dass du an irgendwas und nochwas kommst? Dazu habe ich keinen Code hier gesehen. Oder überlesen???

  • Wo wertest du das dann aus dass du an irgendwas und nochwas kommst? Dazu habe ich keinen Code hier gesehen. Oder überlesen???

    Ganz klar überlesen, da stimme ich Dir zu.

    Kurz umrissen in #4 und etwas ausführlicher im verlinkten Beitrag aus #2.


    Nimm das jetzt bitte nicht krumm, aber vergleiche mal diese beiden Varianten:

    Code: Variante WoltLab
    1. RewriteCond %{SCRIPT_FILENAME} !-d
    2. RewriteCond %{SCRIPT_FILENAME} !-f
    3. RewriteRule ^(.*)$ index.php?seite=$1 [L,QSA]
    Code: vorgeschlagene Variante
    1. RewriteCond %{REQUEST_FILENAME} !-f
    2. RewriteCond %{REQUEST_FILENAME} !-d
    3. RewriteRule ^ index.php [QSA,L]

    Und meine Variante konntest Du nicht zum Laufen bekommen, sagst Du. Siehst Du, das verwundert mich.


    Die ersten beiden Zeilen unterscheiden sich nur in der verwendeten Umgebungsvariablen. Mit {SCRIPT_FILENAME} habe ich selbst die Variante zwar noch nicht gesehen, aber scheint ja dasselbe drin zu stehen, klappt ja.


    Es unterscheidet sich relevant eigentlich nur die letzte Zeile. Der entscheidende Faktor ist der GET-Parameter, den ich mir spare. Ich habe alle Informationen in meiner index.php, die ich brauche.


    Mach mal spaßeshalber in Deine index.php ein var_dump( $_SERVER ); und schau mal, was es dort alles gibt.

    Ich kann mir natürlich die wichtigsten Sachen auch direkt als GET-Parameter mit übermitteln, aber brauchen tut man das halt nicht.


    Die aktuelle Lösung von Dir ist keineswegs falsch! Ich persönlich finde es halt nur umständlich, Parameter zu erfinden, für Werte, die ich auch so schon habe.

    Aber das sollte keine Belehrung o.ä. sein, sondern als Vorschlag dienen.


    Schöne Grüße

  • Ich habe mich nun entschieden, das nach deinem Vorschlag zu lösen. Dabei kam folgende Frage auf:

    Kann ich die beiden Szenarien automatisch auseinander halten, oder muss ich zwei .htaccess-Dateien (lokal, Webserver) nutzen?

  • Hi,


    Ich habe die Frage ehrlich gesagt nicht ganz verstanden. Lokaler- und Webserver sind doch von sich unabhängige Instanzen.

    Natürlich musst Du bei beiden die .htaccess hinterlegen, aber in beiden Fällen ist der Inhalt identisch.


    Oder ich habe die Frage wie gesagt vielleicht nicht verstanden?

  • Natürlich liegt die .htaccess auf beiden Servern. Der Unterschied ist dass beim lokalen Webserver noch ein Unterverzeichnis dazwischen ist. Oben das Verzeichnis "projektname". Dieses besteht auf dem Webserver natürlich nicht. Problem ist nach meiner Meinung die RewriteBase.

  • Vermutlich stimmt etwas mit Deinen Pfaden dann nicht, was sogar sehr wahrscheinlich ist, denn wenn Du schon eine Verzeichnisebene mehr hast auf lokaler Seite, gibt es ja automatisch schon Unterschiede in den Pfaden. Die musste Du natürlich dann anpassen. Deshalb bleibt es sinnvoller für die Bearbeitung den lokalen Webroot zu verwenden oder zumindest entsprechende vhosts in XAMPP anzulegen.


    Mehr kann ich dazu nicht sagen, weil ich Deine Struktur nicht kenn. Du wirfst leider immer nur Bröckchen hier rein, anstatt mal zu posten, was Du aktuell für einen Stand hast.

  • Den letzten Absatz hättest du dir sparen können. Wenn dir Infos fehlen, dann frag strukturiert danach. Woher soll ich wissen, was du wissen musst. Meine Glaskugel ist leider kaputt. Und Romane hier zu schreiben bringt auch nichts, da es niemand liest.

    Ich habe mir nun einen Workarround gebaut, der das HTML-Base an den Server anpasst. Wenn ich die Rewritebase in der htaccess weglasse geht es bis jetzt auch.

    Mir war der Umgang des Webservers mit ist sag mal "virtuellen" Pfaden umgeht. Also Pfade, die es nicht real gibt.

    Wie würdest du die denn eine Entwicklungsumgebung bauen, wenn du mehrere Projekte hast? meinst du domain- oder portbasierte Vhosts?

  • Den letzten Absatz hättest du dir sparen können. Wenn dir Infos fehlen, dann frag strukturiert danach. Woher soll ich wissen, was du wissen musst. Meine Glaskugel ist leider kaputt.

    Hmmm... Ich scrolle nochmal kurz durch den Thread, Moment... Scheint tatsächlich so auszusehen, als wenn ich der einzige war, der Dir überhaupt Hilfestellung geben wollte. Ist es clever, so zu reagieren, wenn man nach Infos fragt, um besser helfen zu können? :/