PHP Mod Rewrite: Problem mit abschließendem Slash in URL

M

Mr. Snoot

Gast
Hio,

ich wandle meinen dynamischen URLs mittels Mod Rewrite in statische um. Wenn ich eine Adresse ohne abschließenden Slash eingebe, dann wird dieser in der URL automatisch hinzugefügt und die Seite wird angezeigt.

a)
Code:
Eingabe: www.halbleiter.org/grundlagen
Wird zu: www.halbleiter.org/grundlagen[COLOR="Red"][B]/[/B][/COLOR]
Nun habe ich neue Inhalte hinzugefügt, bei denen das nicht mehr klappt -> der Slash wird am Ende nicht hinzugefügt, und damit kann die Seite nicht angezeigt werden. Die URL unterscheidet sich dabei nur marginal:

b)
Code:
Eingabe: www.halbleiter.org/[COLOR="seagreen"]en/[/COLOR]fundamentals
Bleibt:  www.halbleiter.org/[COLOR="SeaGreen"]en/[/COLOR]fundamentals

Die Rewrite Rules sind eigentlich identisch, weswegen ich mir das unterschiedliche Verhalten nicht erklären kann.



Im Grunde macht das Rewriting folgendes:

a)
Code:
www.halbleiter.org/hl.php?bereich=grundlagen [COLOR="navy"]wird zu [/COLOR]www.halbleiter.org/grundlagen/
b)
Code:
www.halbleiter.org/hl[COLOR="seagreen"]_en[/COLOR].php?bereich=fundamentals [COLOR="Navy"]wird zu[/COLOR] www.halbleiter.org/[COLOR="seagreen"]en/[/COLOR]fundamentals


Die Rewrite Rules sehen wie folgt aus:

a)
Code:
[COLOR="red"]#eigentliche Umleitung[/COLOR]
RewriteRule ^([^/\.]*)/$ hl.php?bereich=$1
RewriteRule ^([^/\.]*)/([^/\.]*)/$ hl.php?bereich=$1&thema=$2 [QSA]

[COLOR="red"]#dynamische URL in Adressleiste im Browser ändern[/COLOR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/hl\.php\?bereich=([a-z]+)&thema=([a-z]+)
RewriteRule ^hl\.php$ /%1/%2/? [R=301]
RewriteRule ^/([a-z]+)/([a-z]+)/$ hl.php?bereich=$1&thema=$2 [L]

[COLOR="red"]#dynamische URL in Adressleiste im Browser ändern[/COLOR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/hl\.php\?bereich=([a-z]+)
RewriteRule ^hl\.php$ /%1/? [R=301]
RewriteRule ^/([a-z]+)/$ hl.php?bereich=$1 [L]

b)
Code:
[COLOR="red"]#eigentliche Umleitung[/COLOR]
RewriteRule ^en/([^/\.]*)/$ hl_en.php?bereich=$1
RewriteRule ^en/([^/\.]*)/([^/\.]*)/$ hl_en.php?bereich=$1&thema=$2 [QSA]

[COLOR="red"]#dynamische URL in Adressleiste im Browser ändern[/COLOR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/hl_en\.php\?bereich=([a-z]+)&thema=([a-z]+)
RewriteRule ^hl_en\.php$ /en/%1/%2/? [R=301]
RewriteRule ^/en/([a-z]+)/([a-z]+)/$ hl_en.php?bereich=$1&thema=$2 [L]

[COLOR="Red"]#dynamische URL in Adressleiste im Browser ändern[/COLOR]
RewriteCond %{THE_REQUEST} ^[A-Z]+\s/hl_en\.php\?bereich=([a-z]+)
RewriteRule ^hl_en\.php$ /en/%1/? [R=301]
RewriteRule ^/en/([a-z]+)/$ hl_en.php?bereich=$1 [L]
Hat jemand eine Idee, was da schief läuft?


(Das Problem tritt sowohl bei dem Parameter bereich alleine auf, als auch bei bereich und thema zusammen. D.h. der abschließende Slash fehlt im Fall b) immer)
 
Zuletzt bearbeitet:
zeig mal deine php datei, die das ganze managed :)


ich würde das ja ganz anders machen, mit viel weniger htaccess xD
 
Ja, ich stimm Bela B da zu. Mod Rewrite ist zwar toll und cool, aber auch extrem komplex und eigentlich unnötig - zumindest in der Form.

Wenn du deine Scripte komplett selbst programmierst, dann würde ich $_SERVER["REQUEST_URI"] und Whitelists nutzen, um beispielsweise eine url wie

deinedomain.de/en/zieldokument

oder

deinemdomain.de/index.php/en/zieldokument

zu analysieren.


deine .htacces sollte dann nur so aussehen:

Code:
<IfModule mod_rewrite.c>
RewriteEngine On

RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

</IfModule>


Damit leitest du alle Ziele, die nicht existieren, auf die index.php um. Wenn aber eine Datei, die per URL angesprochen wird, auch auf dem server existiert, wird die Datei statt die index.php angesprochen.

Wenn du dann wie gesagt die URI analysierst, mit Whitelists abgleichst usw - dann sparste dir das immense herumgefummel mit mod_rewrite.
 
Hü,

danke, aber das Problem hat sich mittlerweile erledigt, folgender Eintrag erzeugt immer einen abschließenden Slash, sofern nicht vorhanden:
Code:
# Add trailing slash
RewriteCond %{REQUEST_URI} ^/[^\.]+[^/]$
RewriteRule ^(.*)$ http://%{HTTP_HOST}/$1/ [R=301,L]
 
hiho, wo wir beim Thema sind... ich will deswegen nicht unbedingt einen Thread aufmachen, vllt könnt ihr mir auch auf die schnelle helfen...

ich bräuchte dringend einen .htaccess (also mod_rewrite) redirect von

/funbild.php?detail=1942
bzw.
/funbild.php?detail=1942&action=bewerten

auf

/showpic/1942

dabei ist 1942 natürlich durch irgendeine zahl ersetzbar...


könnt ihr mir dabei helfen? wäre echt dringend, wir verlieren google backlinks wie sau :P
 
Ich nehme an, du meinst einen rewrite (keinen redirect), und zwar von /showpic/123 auf /funbild.php?detail=123 (und nicht umgekehrt).


Code:
RewriteEngine on
showpic/(\d+) funbild.php?detail=$1&action=bewerten [L]
 
nein du hast es falsch geschrieben ;)

die ordner auf die du verlinken wirst existieren ja nicht, deswegen schreibt mod_rewrite das ganze auf index.php?... um...
 
naja, ich brauch nen 301 redirect also mit [R=301,L] Flag... sonst beschwert sich google wegen duplicate content.... dafür brauch ichs eigentlich wenn ihrs genau wissen wollt...
 
Du kanst nicht mit mod_rewrite urls wie "/funbild.php?detail=1942" auf "/showpic/1942" linken. Das funktioniert ausschliesslich und vollkommen ohne jedwede Ausnahme nur von "/showpic/1942" auf "/funbild.php?detail=1942".

Wenn du des andersherum haben willst, musst du PHP für nehmen, $_SERVER["REQUEST_URI"] per Regex analysieren und dann ein header("Status: 301 Moved Permanently"); setzen und danach ein header("Location /neuerlink/id"); ausgeben.

So, da das aber Schwachsinn ist und SEO-Technisch unsinn³ ist, musst du dein CMS (oder was auch immer du nutzt) modifizieren, dass er die Links, die der User anklicken können soll, gleich in der korrekten Form ausspuckt.
 
Weißt was? xD

hier ne function, mit der ich arbeite, SEHR praktisch und vor allem einfach :)

function catchParams() {
$str = $_SERVER['REQUEST_URI'];





$i = 0;
$get = array();
$arr = explode('/',$str);


foreach($arr as $key => $val) {
preg_match("(([^\.]*)\.(.*))",$val,$match);
if(isset($match[2])) {
$get[$match[1]] = $match[2];
} else {
$get[$i] = $val;
$i++;
}
}
$params['get'] = $get;
$params['all'] = $get;
$params['post'] = $_POST;
if($_POST && is_array($params['get'])) {
$params['all'] = array_merge($_POST, $params['get']);
} elseif($_POST) {
$params['all'] = $_POST;
}

return $params;
}


am anfang der seite machst einfach $params = catchParams();



und in der htacces folgendes:

RewriteEngine On
RewriteBase /

RewriteRule ^(.*) index.php [L]

und dann noch die ordner, die aus der rewriterule ausgeschlossen werden, bsp:
RewriteRule ^templates/(.*) templates/$1 [L]






/funbild.php?detail=1942
bzw.
/funbild.php?detail=1942&action=bewerten


WIRD MIT MEINER FUNCTION ZU

/funbild/detail.1942/action.bewerten/

bzw so würds auch gehn:

/funbild/1942/bewerten/




<?php
$detail = $params['get']['detail'] (=1942)
$detail = $params['get']['action'] (=bewerten)

$phpDatei = $params['get'][1];

include $phpDatei.".php";


zb xD
?>
 
Zuletzt bearbeitet: (erweiterung d. beitrages)
Nette Idee, reicht für Scripte die man selbst einsetzt. Für Scripte, die beispielsweise auch für andre gedacht sind ist dedd nix^^

btw: Du sollstest ggf. noch den Request uri prüfen auf /index.php und das rausfiltern. Ich weiß Eine Whitelist wäre btw auch sinnvoll um ungewünschten Parametern keine Chance zu geben ;)

Achso, und du verarbeitest $_POST und $_GET gleichermaßen? Würde ich nicht machen, weil du so ggf. vorhandene GET-Params mit übergebenen POST-Params überschreiben könntest.
 

Ähnliche Themen

M
Antworten
0
Aufrufe
895
Mr. Snoot
M
Zurück
Oben