2 Variablen per .htaccess an PHP übergeben (RegEx)
pipinator
- webserver
Hallo,
ich bin kein Profi und habe schon lange keine Seite mehr gebaut.
Der Einfachheit halber wollte ich eine funktionierende RewriteRule kürzen und siehe da, sie funktioniert dann nicht mehr. :)
Diese tut ihren Dienst einwandfrei:
RewriteRule ^([a-z][a-z])/?([0-9a-z_-]*)/?([0-9a-z_-]*)?/?$ ?SeitenParameter1=$1&SeitenParameter2=$2&SeitenParameter3=$3
Jetzt habe ich aber keine zweite Sprache (eigentlicher Parameter 1) und deswegen wollte ich ([a-z][a-z])/? weglassen, damit nur noch die beiden anderen Variablen gefüllt werden.
Sieht dann so aus:
RewriteRule ^([0-9a-z_-]*)/?([0-9a-z_-]*)?/?$ ?SeitenParameter1=$1&SeitenParameter2=$2
Das funktioniert dann aber nicht mehr. Die Variable $SeitenParameter1 (via $_GET['SeitenParameter1']) wird zwar gesetzt, hat aber keinen Inhalt.
Stopp ich den Server wieder, trage wieder die alte Version ein und starte den Server wieder, kommen wieder gesetzte Variablen mit korrektem Inhalt an.
Was übersehe ich dabei?
Mahlzeit,
Was übersehe ich dabei?
Die Bedeutung von ^
Die Bedeutung von ^
Tut mir leid, aber das sagt mir so nichts.
Hab nochmals auf zahlreichen Seiten nachgelesen, dass ^, wenn es nicht innerhalb einer eckigen Klammer steht, den Anfang eines regulären Ausdrucks markiert.
Und das tut es in meinen beiden Beispielen irgendwie musterhaft. :)
Siehe z.B.:
http://de.wikipedia.org/wiki/Regexp#Weitere_Zeichen
Mahlzeit,
Hab nochmals auf zahlreichen Seiten nachgelesen, dass ^, wenn es nicht innerhalb einer eckigen Klammer steht, den Anfang eines regulären Ausdrucks markiert.
Kann es nicht eher sein, dass es den Anfang des zu prüfenden Strings markiert?
Kann es nicht eher sein, dass es den Anfang des zu prüfenden Strings markiert?
Okay, kann es.
Un nu?
Mahlzeit,
Un nu?
Wenn du den String von Anfang an prüfst, musst du sicherstellen, dass das, was am Anfang steht auch in der Rule steht.
Entweder lässt du das ^ weg, dann wird mitten im String geprüft oder du lässt alles so, wie es funktioniert und ignorierst $1 einfach.
Wenn du den String von Anfang an prüfst, musst du sicherstellen, dass das, was am Anfang steht auch in der Rule steht.
Entweder lässt du das ^ weg, dann wird mitten im String geprüft oder du lässt alles so, wie es funktioniert und ignorierst $1 einfach.
Okay, langsam dämmerts. :)
Ich bin irrtümlich davon ausgegangen, weil meine erste Rule funktionierte, dass erst nach der Domain geprüft wird.
Herzlichen Dank.
Hi,
Diese tut ihren Dienst einwandfrei:
RewriteRule ^([a-z][a-z])/?([0-9a-z_-]*)/?([0-9a-z_-]*)?/?$ ?SeitenParameter1=$1&SeitenParameter2=$2&SeitenParameter3=$3
Die Parameter werden also einfach an das per DirectoryIndex gesetzte Default-Dokument für das Verzeichnis weitergeleitet – ich nehme an, dass ist bei dir eine index.php o.ä.?
Jetzt habe ich aber keine zweite Sprache (eigentlicher Parameter 1) und deswegen wollte ich ([a-z][a-z])/? weglassen, damit nur noch die beiden anderen Variablen gefüllt werden.
Sieht dann so aus:
RewriteRule ^([0-9a-z_-]*)/?([0-9a-z_-]*)?/?$ ?SeitenParameter1=$1&SeitenParameter2=$2
Das funktioniert dann aber nicht mehr. Die Variable $SeitenParameter1 (via $_GET['SeitenParameter1']) wird zwar gesetzt, hat aber keinen Inhalt.
Und wie lautet die Adresse, die du aufrufst?
MfG ChrisB
Die Parameter werden also einfach an das per DirectoryIndex gesetzte Default-Dokument für das Verzeichnis weitergeleitet – ich nehme an, dass ist bei dir eine index.php o.ä.?
Richtig, eine index.php prüft ob die GET-Variable gesetzt ist und übergibt gegebenenfalls den Wert an eine String-Variable:
if (isset ($_GET['SeitenParameter1'])) {$SeitenParameter1=$_GET['SeitenParameter1'];}
if (isset ($_GET['SeitenParameter2'])) {$SeitenParameter2=$_GET['SeitenParameter2'];}
Und wie lautet die Adresse, die du aufrufst?
Z.B. domain.de/bla/blubb.
હેલો
Und wie lautet die Adresse, die du aufrufst?
Z.B. domain.de/bla/blubb.
Wieso machst du das nicht gleich in PHP, statt über htaccess?
„domain.de/bla/blubb“ kürzen auf „/bla/blubb“ und das resultat in die Luft jagen.
<?php
$_requestUri = "/bla/blubb";
print_r ( explode('/', $_requestUri) );
બાય
Wieso machst du das nicht gleich in PHP, statt über htaccess?
„domain.de/bla/blubb“ kürzen auf „/bla/blubb“ und das resultat in die Luft jagen.
<?php
$_requestUri = "/bla/blubb";
print_r ( explode('/', $_requestUri) );
>
> બાય
Die Idee, anstatt .htaccess $\_SERVER['REQUEST\_URI'] zu verwenden find ich klasse.
Herzlichen Dank.
Tach!
Richtig, eine index.php prüft ob die GET-Variable gesetzt ist und übergibt gegebenenfalls den Wert an eine String-Variable:
if (isset ($_GET['SeitenParameter1'])) {$SeitenParameter1=$_GET['SeitenParameter1'];}
if (isset ($_GET['SeitenParameter2'])) {$SeitenParameter2=$_GET['SeitenParameter2'];}
Warum kopierst du die "Stringvariable" $\_GET['SeitenParameter1'] nochmal in eine andere "Stringvariable"? Und was ist, wenn es $\_GET['SeitenParameter1'] nicht gibt? Fehlt dann dem Script $SeitenParameter1?
dedlfix.
Warum kopierst du die "Stringvariable" $_GET['SeitenParameter1'] nochmal in eine andere "Stringvariable"? Und was ist, wenn es $_GET['SeitenParameter1'] nicht gibt? Fehlt dann dem Script $SeitenParameter1?
Ist alles richtig, was Du schreibst. Die Zeilen sind nur noch nicht fertig, die sollten erst mal bei der Fehlersuche bei der RewriteRule helfen.
Trotzdem Danke ich Dir, dass Du mich auf die Schwachstellen aufmerksam machst.
Ich hab da noch mal ne Frage.
Um zu testen, was letztendlich in dem String steht, der durch meine RewriteRule läuft, wollte ich mal einfach den kompletten String per $_GET nach PHP holen und ausgeben lassen.
Leider hat das nicht geklappt. Ich bekomme nur eine gesetzte aber leere Variable.
Weder mit
RewriteRule ^*$ ?SeitenParameter1=$1
noch mit
RewriteRule ^([*]*)$ ?SeitenParameter1=$1
oder mit
RewriteRule ^([A-Za-z0-9_-/:.]*)$ ?SeitenParameter1=$1
Warum nicht?
Hi,
Weder mit
RewriteRule ^*$ ?SeitenParameter1=$1
noch mit
RewriteRule ^([*]*)$ ?SeitenParameter1=$1
oder mit
RewriteRule ^([A-Za-z0-9_-/:.]*)$ ?SeitenParameter1=$1
Warum nicht?
Weil Rewriting im Kontext von .htaccess immer „neu gestartet” wird, bis es nichts mehr zum Umschreiben gibt. (Das ist anders, wenn es in der zentralen Server-Konfiguration … nun ja, konfiguriert wurde.)
Betrachten wir mal beispielshabler nur die erste Rule die du angeführt hast, mit den anderen verhält es sich analog:
Was du hier also hast, ist dass dein Request nach /foo-bar rein kommt, und deine RewriteRule matched (sie matched auf foo-bar
, der führende Slash wird nicht betrachtet) – und dein Request wird umgeschrieben zu /?SeitenParameter1=foo-bar. So, keine weiteren Regeln, wir sind fertig – für *diese* Runde.
Aber, weil wegen siehe oben – es wird eine neue Runde gestartet, mit dem neuen internen Request, /?SeitenParameter1=foo-bar.
Die RewriteRule betrachtet bekanntlich nur die path-Komponente des URL, das ist hier nichts weiter als / – und da der führende Slash ignoriert wird, betrachten wir hier letztendlich nur noch einen *leeren* Pfad. Auf den matched jeder deiner aufgeführten regularen Ausdrücke, weil du alles was deine verschiedenen Muster abdecken ja nur *optional* verlangst, durch den Stern-Quantifier.
Also erfolgt jetzt ein Umschreiben auf /?SeitenParameter1=
– deinen leeren Pfad findest du hinter dem Gleichheitszeichen wieder. Und so geht’s dann weiter, in die nächste Runde (eigentlich müsstest du hier einen Fehler bekommen, dass das Umschreiben nicht beendet werden konnte – aber abhängig von der weiteren Konfiguration kann der u.U. auch ausbleiben).
Was du dagegen machen kannst – nun, da gibt’s unterschiedliche Ansätze und Möglichkeiten.
Du könntest einen leeren Pfad ausschließen, in dem du mit + statt * einen mindestens ein Zeichen langen Match verlangst.
Du könntest statt auf ?SeitenParameter1=
explizit auf index.php?SeitenParameter1=
umleiten, und das Umschreiben nur unter der Bedingung stattfinden lassen, dass index.php
im Request-Path *nicht* vorkommt.
Was oft gemacht wird, ist nur umzuschreiben, wenn der Request nicht zu einer vorhandenen Datei oder einem vorhandenen Verzeichnis aufgelöst werden kann – mit RewriteConds vor der RewriteRule, die das mit den Flags -d/-f bzw. deren Negierungen vorab überprüfen.
Das ist *üblicherweise* genau der Fall, den man haben will – physisch als Dateien vorhandene Ressourcen (Bilder, Scripte, Stylesheets, …) werden nicht umgeschrieben, sondern der Default-Auslieferungsmechanismus des Apachen beantwortet diese Requests mit dem jeweiligen Dateiinhalt.
Und alles andere, für das nichts physisch vorhanden ist, schreibt man um auf das Script, das dann den passenden Inhalt aus einer anderen Datenquelle (z.B. der Datenbank) heraussucht, und den Request dann selber mit diesem Inhalt beantwortet.
MfG ChrisB