Comment éviter les boucles dans les exceptions des règles regex génériques?

Besoin d’utiliser des drapeaux ? RewriteCond ? Le mod_rewrite est activé et en cours d’exécution, mon problème est de savoir comment exprimer mes besoins: il existe une règle générique et des exceptions à la règle, les exceptions ne fonctionnent pas et la solution doit éviter les boucles.

Mon /var/www avant d’utiliser mod_rewrite , travaillait avec les dossiers habituels comme /var/www/wiki , /var/www/foo , /var/www/bar (chacun avec son index). Je dois préserver ce comportement.

Maintenant, avec mod_rewrite , j’utilise un /var/www/index.php pour redirect certaines chaînes spéciales qui correspondent à ^([a-z0-9]+) , telles que http://myDomain/foo123 ou http://myDomain/wiikii . Mais cela correspond aussi à “wiki” et à “foo”, qui nécessitent une gestion des exceptions .


Mon /var/www/.htaccess est

  RewriteEngine on RewriteRule ^/?(foo|bar)([0-9]+) index.php?$1=$2 RewriteRule ^/?([a-z0-9]+) index.php?foobar=$1 

Donc, quelque chose comme http://myDomain/wiki est redirigé vers index.php?foobar=wiki , mais j’en ai besoin sans redirection , Apache doit aller sur /wiki .

PS: J’essaie quelques variantes et quelques modifications dans index.php (en travaillant avec des redirections en interne), mais j’ai besoin d’ une solution Apache Rewrite élégante et sécurisée, évitant les boucles .

Les conditions sont généralement la voie à suivre, en vérifiant avec REQUEST_URI.

  RewriteCond %{REQUEST_URI} !^/(wiki|foo)$ <-- added RewriteRule ^([a-z0-9]+)$ index.php?foobar=$1 [L] 

Une alternative consiste à utiliser, par exemple, le lookahead négatif dans votre regex. Par exemple:

  RewriteRule ^(?!(?:foo|wiki)$)([a-z0-9]+) ... 

Mais je trouve que certaines des assertions de largeur zéro sont assez compliquées / fragiles / non intuitives, même si les expressions rationnelles normales vous sont assez faciles.

?! est le lookahead négatif?: est juste non-capture des parens pour le "ou"

La partie la plus déroutante à ce sujet est que le pcre s'efforce de trouver un moyen de ne PAS satisfaire la tête de lecture négative, c'est-à-dire qu'il s'efforce de réussir une correspondance globale.

Si vous ne voulez pas de redirection pour les dossiers wiki (et autres), vous pouvez append une condition

 RewriteEngine on # If requested url is an existing file or folder, don't touch it RewriteCond %{REQUEST_FILENAME} -d [OR] RewriteCond %{REQUEST_FILENAME} -f RewriteRule . - [L] # If we reach here, this means it's not a file or folder, we can rewrite... RewriteRule ^(foo|bar)([0-9]+)$ index.php?$1=$2 [L] RewriteRule ^([a-z0-9]+)$ index.php?foobar=$1 [L] 

En outre, vous pouvez utiliser une sorte d’ exception si vous ne souhaitez pas qu’elle soit appliquée à tous les dossiers / fichiers.

 RewriteEngine on # If requested url is a folder/file in exception list, don't touch it RewriteCond %{REQUEST_URI} ^/(foo|bar|example_file\.html|wiki)$ RewriteRule . - [L] # If we reach here, this means it's not a file or folder in exception list, we can rewrite... RewriteRule ^(foo|bar)([0-9]+)$ index.php?$1=$2 [L] RewriteRule ^([a-z0-9]+)$ index.php?foobar=$1 [L]