mod_rewrite zerstört Unicodes?
Chris
- php
Hallo ihr,
ich habe Variablen, die verschiedene Sonderzeichen enthalten. Damit ich diese per GET fehlerfrei übermitteln kann, lasse ich vorher urlencode() anwenden.
Ganz einfaches Beispiel:
$test = "Bremen & Oldenburg";
$test = urlencode($test); // $test hat jetzt den Wert "Bremen%20%26%20Oldenburg"
Diesen String übergebe ich also per GET... die Adresse sieht dann zb so aus:
region_Bremen%20%26%20Oldenburg.html
Per mod_rewrite wird das an eine andere Datei weitergeleitet und zwar:
content/region/index.php?rg=Bremen%20%26%20Oldenburg
Wenn ich mir die Variable dann auf der Seite ausgeben lasse, ist davon nur noch übrig: Bremen
Der Rest fehlt. Zerstört die Weiterleitung per mod_rewrite also meine Sonderzeichen? Wenn ich die oben genannte Seite direkt aufrufe, ist die Ausgabe so, wie sie sein soll. Wenn ich aber die per mod_rewrite erzeugte Datei aufrufe, fehlt ab dem ersten Leerzeichen alles.
Gibt es eine Lösung dafür? Oder wenigstens eine Erklärung?
Grüße
Chris
Lieber Chris,
$test = urlencode($test); // $test hat jetzt den Wert "Bremen%20%26%20Oldenburg"
und was passiert, wenn Du stattdessen rawurlencode() benutzt?
Liebe Grüße aus Ellwangen,
Felix Riesterer.
und was passiert, wenn Du stattdessen rawurlencode() benutzt?
Hey Felix,
sieht für mich nach dem gleichen Problem aus... das Verhalten hat sich nicht geändert, leider.
Grüße
Chris
Hey,
ich habe jetzt zumindest eine Lösung, die funktioniert. Ob das jetzt wirklich DIE Lösung ist, weiß ich nicht.
function hexEncode($string){
$hex='';
for ($i=0; $i < strlen($string); $i++){
$hex .= dechex(ord($string[$i]));
}
return $hex;
}
function hexDecode($hex){
$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2){
$string .= chr(hexdec($hex[$i].$hex[$i+1]));
}
return $string;
}
Diese beiden Funktionen wandeln den String in Hexcodes um, und wieder zurück. Der Hexcode kann wunderbar in der URL übertragen werden, das macht auch mod_rewrite mit.
Nachteil natürlich: Man hat die entsprechende Seite nicht mehr im Klartext in der Adresszeile, was natürlich in Bezug auf Suchmaschinen grade eine der Stärken von mod_rewrite ist. Aber man muss das Prinzip ja nicht überall anwenden, sondern nur da, wo das übermitteln von Sonderzeichen per URL unvermeidlich ist.
Ich bin damit zufrieden. Aber hat vielleicht trotzdem jemand eine bessere Lösung?
Grüße
Lars
Hi,
Per mod_rewrite wird das an eine andere Datei weitergeleitet und zwar:
content/region/index.php?rg=Bremen%20%26%20Oldenburg
Wenn ich mir die Variable dann auf der Seite ausgeben lasse, ist davon nur noch übrig: Bremen
Der Rest fehlt.
Zerstört die Weiterleitung per mod_rewrite also meine Sonderzeichen?
Nein, im allgemeinen ist mod_rewrite nicht sonderlich destruktiv.
Wenn $ich die oben genannte Seite direkt aufrufe, ist die Ausgabe so, wie sie sein soll. Wenn ich aber die per mod_rewrite erzeugte Datei aufrufe, fehlt ab dem ersten Leerzeichen alles.
Was sagt das rewrite_log?
MfG ChrisB
Hello,
content/region/index.php?rg=Bremen%20%26%20Oldenburg
Wenn ich mir die Variable dann auf der Seite ausgeben lasse, ist davon nur noch übrig: Bremen
Wie wird denn diese Variable "auf der Seite" ausgegeben?
Fehlen vielleicht einfach die Häkchen um das value-Attribut des <input>-Elementes?
echo "<input type=text value=" . $_GET['rg'] . ">";
wäre FALSCH!
echo "<input type="text" value="" . htmlspecialchars($_GET['rg']) . "">";
müsste funktionieren.
Ein harzliches Glückauf
Tom vom Berg
Wie wird denn diese Variable "auf der Seite" ausgegeben?
Hallo,
siehe meinen Eintrag, den auf das Posting von ChrisB verfasst habe. Ich habe eine Testpage erstellt, die man mit einem GET-Parameter aufrufen kann, und die dann per echo einfach die Variable wiedergibt.
http://87.106.49.169/test.php?var=Bremen+%26+Oldenburg
http://87.106.49.169/test_Bremen+%26+Oldenburg.html
Beides die gleiche Seite - das eine funktioniert, das andere nicht.
Grüße
Chris
- *Wie* *genau* gibst du den Inhalt des GET-Parameters aus?
- print_r($_SERVER) ergibt was? (relevante Bestandteile)
Hallo,
ich habe jetzt mal ne ganz einfache Testpage erstellt, die test.php. Der Inhalt sieht so aus:
<?
echo $_GET['var'];
?>
Nun kann man diese einmal so aufrufen:
test.php?var=Bremen+%26+Oldenburg
Oder auch so:
test_Bremen+%26+Oldenburg.html
Der Eintrag in der .htaccess sieht so aus:
RewriteEngine on
RewriteRule test_(.*).html$ test.php?var=$1
Die Seite hab ich online gestellt:
Ohne mod_rewrite: http://87.106.49.169/test.php?var=Bremen+%26+Oldenburg
Mit mod_rewrite: http://87.106.49.169/test_Bremen+%26+Oldenburg.html
Da sieht man die Problematik auch...
Die rewrite_log sieht so aus:
applying pattern 'test_(.*).html$' to uri 'test_Bremen+&+Oldenburg.html'
rewrite 'test_Bremen+&+Oldenburg.html' -> 'test.php?var=Bremen+&+Oldenburg'
uri=test.php, args=var=Bremen+&+Oldenburg
add per-dir prefix: test.php -> C:/Web/WebPages/WebChatSolutions/htdocs/test.php
strip document_root prefix: C:/Web/WebPages/WebChatSolutions/htdocs/test.php -> /test.php
internal redirect with /test.php [INTERNAL REDIRECT]
strip per-dir prefix: C:/Web/WebPages/WebChatSolutions/htdocs/test.php -> test.php
applying pattern 'test_(.*).html$' to uri 'test.php'
pass through C:/Web/WebPages/WebChatSolutions/htdocs/test.php
Man sieht, dass er aus dem %26 in der URL direkt ein &-Zeichen gemacht hat. Das dürfte das Problem sein... aber ich frage mich, wieso er %26 in ein & umwandelt, wo ich es doch extra mit urlencode() maskiert habe, damit es KEINE probleme gibt...
Grüße
Chris
echo $begrüßung;
- *Wie* *genau* gibst du den Inhalt des GET-Parameters aus?
echo $_GET['var'];
Für genaueere Ausgaben empfiehlt sich var_dump() statt echo. var_dump() gibt bei Strings nämlich noch die Länge an und zeigt den Wert in Begrenzungszeichen an. Es ist dann bei Bremen im Beispiel mit mod_rewrite die Länge 7 und ein anhängendes Leerzeichen deutlicher zu sehen.
- print_r($_SERVER) ergibt was? (relevante Bestandteile)
Der Inhalt von $_SERVER (oder auch der unteren Teil einer phpinfo()-Ausgabe) wäre ebenfalls interessant, denn da kannst du genauer sehen, welche Werte PHP erreichen. Das %26 wird von mod_rewrite in ein einfaches & gewandelt (siehe unten), weswegen PHP es als Parametertrennzeichen ansieht.
Der Eintrag in der .htaccess sieht so aus:
RewriteEngine on
RewriteRule test_(.*).html$ test.php?var=$1
[...]
Die rewrite_log sieht so aus:
applying pattern 'test_(.*).html$' to uri 'test_Bremen+&+Oldenburg.html'
[...]
Man sieht, dass er aus dem %26 in der URL direkt ein &-Zeichen gemacht hat. Das dürfte das Problem sein... aber ich frage mich, wieso er %26 in ein & umwandelt, wo ich es doch extra mit urlencode() maskiert habe, damit es KEINE probleme gibt...
Schau dir im Apache-Handbuch zu RewriteRule die Beschreibung des Flags B (escape backreferences) an. Das dürfte deines Rätsels Lösung sein.
echo "$verabschiedung $name";
Schau dir im Apache-Handbuch zu RewriteRule die Beschreibung des Flags B (escape backreferences) an. Das dürfte deines Rätsels Lösung sein.
Du hast Recht, das klingt als könnte es das Problem lösen. Aber wie werden diese Flags angewendet? Mit meinen Versuchen lande ich immer in einem HTTP 500 Fehler. Die Bedingung als solches kann doch bleiben, nur das Flag muss hinten ran?
Grüße
Chris
echo $begrüßung;
Schau dir im Apache-Handbuch zu RewriteRule die Beschreibung des Flags B (escape backreferences) an. Das dürfte deines Rätsels Lösung sein.
Du hast Recht, das klingt als könnte es das Problem lösen. Aber wie werden diese Flags angewendet? Mit meinen Versuchen lande ich immer in einem HTTP 500 Fehler. Die Bedingung als solches kann doch bleiben, nur das Flag muss hinten ran?
Diese Flags kommen in eckigen Klammern hintendran. Allerdings sehe ich gerade, dass [B] erst ab Version 2.2 existiert. Das 2.0 und 1.3-er Handbuch kennen dieses Flag nicht. Eine andere Lösung außer einem doppelten Escapen fällt mir nicht ein. Ich denke aber, dass du nicht der erste mit diesem Problem bist und selbiges irgendwo im Netz schon erörtert worden ist ...
500er Fehler können mehrere Ursachen haben. Im ErrorLog steht eine aussagekräftigere Information.
echo "$verabschiedung $name";
Hello,
Das %26 wird von mod_rewrite in ein einfaches & gewandelt (siehe unten), weswegen PHP es als Parametertrennzeichen ansieht.
Dann fehlt doch nur noch das Encoding für den Kontext...
http://de2.php.net/manual/en/function.rawurlencode.php [erl]
http://de2.php.net/manual/en/function.htmlspecialchars.php [ ]
Ein harzliches Glückauf
Tom vom Berg
echo $begrüßung;
Das %26 wird von mod_rewrite in ein einfaches & gewandelt (siehe unten), weswegen PHP es als Parametertrennzeichen ansieht.
Dann fehlt doch nur noch das Encoding für den Kontext...
http://de2.php.net/manual/en/function.rawurlencode.php [erl]
http://de2.php.net/manual/en/function.htmlspecialchars.php [ ]
Nach einer URL-Kodierung bleibt für htmlspecialchars() keine Arbeit mehr übrig. Diese Funktion lässt sich auch nicht dem mod_rewrite unterschieben.[1] Ihr Einsatz schadet jedoch nicht, ist aber nur erforderlich, wenn mehrere URL-kodierte Werte mit & getrennt in einer URL notiert werden sollen.
[1] Abgesehen davon mag PHP kein & sonden nur & als Trennzeichen erkennen[2]. Das & muss der Browser bereits wieder zu einem & gemacht haben.
[2] arg_separator.input mal unbeachtet gelassen.
echo "$verabschiedung $name";
Hi,
Die Seite hab ich online gestellt:
Ohne mod_rewrite: http://87.106.49.169/test.php?var=Bremen+%26+Oldenburg
Mit mod_rewrite: http://87.106.49.169/test_Bremen+%26+Oldenburg.htmlDa sieht man die Problematik auch...
Bei zweiterer Adresse bekomme ich lediglich einen 404, d.h. deine RewriteRule greift offenbar gar nicht.
MfG ChrisB