2008-09-22 11 views
11

Je construis un site web assez grand et mon .htaccess commence à se sentir un peu gonflé, y at-il un moyen de remplacer mon système actuel de - une règle pour chacun des possibile nombre de vars qui pourraient être passés, à un attraper toutes les expressions qui peuvent expliquer le nombre variable d'entrées?apache mod_rewrite une règle pour n'importe quel nombre de possibilités

par exemple, j'ai actuellement:

RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4&$5=$6 
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4 
RewriteRule ^([a-z]+)/([^/]*)$ /index.php?mode=$1&id=$2 
RewriteRule ^([a-z]+)$ /index.php?mode=$1 

la première backreference est toujours le mode et (le cas échéant plus existe), le second est toujours id, par la suite une autre plus de références arrières entre le nom de l'entrée et sa valeur

http://www.example.com/search 
http://www.example.com/search/3039/sort_by/name_asc/page/23 

J'aimerais pouvoir avoir une expression pour gérer avec élégance toutes les entrées.

+0

Ce n'est pas gonflé :) Vous devriez avoir vu certaines de mes configs apache. Sérieusement, 4 lignes de règles de réécriture est parfaitement raisonnable. – Aeon

+0

c'est juste une section de ma config que je sentais que je pourrais améliorer, mais je ne sais pas comment, il ya d'autres sections que je travaille actuellement;) – JimmyJ

Répondre

8

Faites comme Drupal:

RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 

Et puis gérer tous les trucs dans votre script en utilisant le code php quelque chose comme ça

$pathmap =(); 
if ($_GET["q"]){ 
    $path = split("/", $_GET["q"]); 
    for ($i=0; $i+1<count($path); $i++){ 
     $pathmap[$path[$i]] = $path[$i+1]; 
     $i++; 
    } 
} 
+0

pas exactement ce que je cherchais mais une bonne alternative néanmoins – JimmyJ

+0

Comment faire vous gérer cela dans le script plus tard? –

2

Je ne crois pas que leur est une façon - mais je Dites que votre meilleur pari serait d'avoir le script "index.php" traiter un chemin au lieu d'avoir à faire autant de références.

Ainsi, par exemple, votre rewriterule serait

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

ou similaire ... Ce serait alors faire la variable $ _SERVER [ « REQUEST_URI »] contient les informations de chemin, que vous pouvez partager et analyser.

$path = split('/', $_SERVER['REQUEST_URI']); 
array_shift($path); // We always have a first null value 
$mode = array_shift($path); 

Cela finit avec le mode $ contenant le mode, et le chemin de $ contenant un ensemble d'éléments qui sont le reste de votre chemin, si

http://example.com/foo/bar/baz 

vous laisserions $ mode étant « foo 'et $ path étant un tableau contenant' bar 'et' baz '

+0

Ne fonctionne pas comme prévu car $ _SERVER ['REQUEST_FILENAME'] doit être $ _SERVER ['REQUEST_URI'] et $ mode est toujours vide. Le principe est bon cependant. – da5id

+0

Correction des problèmes que vous avez signalés – Mez

7

Je ne sais pas si cela peut être fait avec une seule expression, mais cela peut être fait avec un nombre fixe d'expressions, peu importe la durée la chaîne de requête.

Vos règles mod_rewrite seront appelées à plusieurs reprises, ce qui vous donnera ce que l'on appelle parfois la récursivité mod_rewrite. Il existe des techniques pour l'éviter, mais je pense que vous voulez l'utiliser.

Mettre en place une règle qui remplace la dernière paire avec le nom = valeur &

sur la clouant Conserver chaîne de requête d'entrée à la sortie. À chaque fois, votre chaîne de requête s'allongera et votre URL sera plus courte.

Finalement, vous n'avez qu'une seule valeur qui correspond à votre dernière règle.

Vous avez à capturer la chaîne de requête avec

RewriteCond %{QUERY_STRING} ^(.*)$ 

Et puis vous ajoutez de nouveau à la sortie avec 1%

Vous finiriez avec quatre lignes.

Je connais quatre lignes avec lesquelles vous avez commencé, mais vous pouvez faire correspondre autant de paramètres que vous le souhaitez sans avoir à ajouter une cinquième ligne.

RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L] 
RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^([^/]+)/ $1.php?%1 [L] 

Cela réécrire les éléments suivants

/mypage/param1/val1/param2/val2/param3/val3/...  ---> 
/mypage.php?param1=val1&param2=val2&param3=val3&... 

Il arrête quand il n'y a qu'un seul paramètre reste. Il prendra le premier "paramètre" et appellera le fichier .php avec ce nom. Il n'y a pas de limite au nombre de paires param/val.

+0

Merci pour ce commentaire. Cela a certainement aidé une autre question (pas sur SO). –

Questions connexes