Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Candidat au Club
    [URL Rewriting] flag last [L] ne fonctionnant pas
    bonjour,

    Nous essayons de faire une manip assez simple du type
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    RewriteRule ^index\.php$ /contact.php [L]
    RewriteRule ^contact\.php$ presentation.php [L]


    Nous avons testé cet exemple chez au moins deux hébergeurs et le flag [L] semble ne pas fonctionner pour nous, nous arrivons toujours sur la page presentation.php lorsqu'on demande index.php c'est à dire que les deux réécritures sont effectuées.

    Merci de votre aide

  2. #2
    Rédacteur

    Oui : c'est parce qu'on pense toujours que L arrête pour de bon le mécanisme des RewriteRule mais ce n'est pas le cas. Il arrête juste la boucle en cours, mais il ne bloque pas totalement la boucle globale : il reprend les règles depuis le début pour processer l'URL réécrite :
    Code doc Apache :Sélectionner tout -Visualiser dans une fenêtre à part
    Remember, however, that if the RewriteRule generates an internal redirect (which frequently occurs when rewriting in a per-directory context), this will reinject the request and will cause processing to be repeated starting from the first RewriteRule.

    Doc, pour ton cas, tu demandes index.php. La première s'applique et on obtient l'URL interne /contact.php. Le L dit de ne pas continuer pour ce /index.php, mais présentement, on a une nouvelle URL interne /contact.php à processer, donc on recommence : /contact.php ne matche pas la première règle mais la seconde, et on tombe sur une nouvelle réécriture vers /presentation.php qui va repartir dans la boucle. On parcourt donc pour la 3ème fois à travers les règles. Rien ne matche, donc on se retrouve avec l'URL finale /presentation.php. Si tu veux t'en convaincre, tu peux activer les log du mod_rewrite et regarder ce qu'il est dit :
    [rid#ec4730/initial] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/index.php -> index.php
    [rid#ec4730/initial] (3) [perdir C:/wamp/www/] applying pattern '^index\.php$' to uri 'index.php'
    [rid#ec4730/initial] (2) [perdir C:/wamp/www/] rewrite 'index.php' -> '/contact.php'
    [rid#ec4730/initial] (1) [perdir C:/wamp/www/] internal redirect with /contact.php [INTERNAL REDIRECT]
    [rid#ed3350/initial/redir#1] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/contact.php -> contact.php
    [rid#ed3350/initial/redir#1] (3) [perdir C:/wamp/www/] applying pattern '^index\.php$' to uri 'contact.php'
    [rid#ed3350/initial/redir#1] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/contact.php -> contact.php
    [rid#ed3350/initial/redir#1] (3) [perdir C:/wamp/www/] applying pattern '^contact\.php$' to uri 'contact.php'
    [rid#ed3350/initial/redir#1] (2) [perdir C:/wamp/www/] rewrite 'contact.php' -> 'presentation.php'
    [rid#ed3350/initial/redir#1] (3) [perdir C:/wamp/www/] add per-dir prefix: presentation.php -> C:/wamp/www/presentation.php
    [rid#ed3350/initial/redir#1] (2) [perdir C:/wamp/www/] strip document_root prefix: C:/wamp/www/presentation.php -> /presentation.php
    [rid#ed3350/initial/redir#1] (1) [perdir C:/wamp/www/] internal redirect with /presentation.php [INTERNAL REDIRECT]
    [rid#f42b88/initial/redir#2] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#f42b88/initial/redir#2] (3) [perdir C:/wamp/www/] applying pattern '^index\.php$' to uri 'presentation.php'
    [rid#f42b88/initial/redir#2] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#f42b88/initial/redir#2] (3) [perdir C:/wamp/www/] applying pattern '^contact\.php$' to uri 'presentation.php'
    [rid#f42b88/initial/redir#2] (1) [perdir C:/wamp/www/] pass through C:/wamp/www/presentation.php
    [rid#eca740/initial] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#eca740/initial] (3) [perdir C:/wamp/www/] applying pattern '^index\.php$' to uri 'presentation.php'
    [rid#eca740/initial] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#eca740/initial] (3) [perdir C:/wamp/www/] applying pattern '^contact\.php$' to uri 'presentation.php'
    [rid#eca740/initial] (1) [perdir C:/wamp/www/] pass through C:/wamp/www/presentation.php
    [rid#56d4a20/initial] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#56d4a20/initial] (3) [perdir C:/wamp/www/] applying pattern '^index\.php$' to uri 'presentation.php'
    [rid#56d4a20/initial] (3) [perdir C:/wamp/www/] strip per-dir prefix: C:/wamp/www/presentation.php -> presentation.php
    [rid#56d4a20/initial] (3) [perdir C:/wamp/www/] applying pattern '^contact\.php$' to uri 'presentation.php'
    [rid#56d4a20/initial] (1) [perdir C:/wamp/www/] pass through C:/wamp/www/presentation.php
    Maintenant, pour la correction, dans ton cas, tu as le choix. Soit tu changes le nom de tes scripts pour qu'il n'y ait pas confusion entre une redirection "URL rewriting" vers la page de contact et la demande explicite par l'utilisateur de la page de contact. Soit tu appliques une méthode plus classique pour les problèmes de ce genre : ajouter des RewriteCond. Pour faire ça, faut gruger pour qu'Apache fasse la différence entre un accès explicite par l'utilisateur à /contact.php et la redirection interne par réécriture vers /contact.php. La solution que je te propose c'est d'ajouter un paramètre d'URL "dummy" dans la première RewriteRule pour notifier que le /contact.php qui sort est le fruit d'une réécriture et de vérifier la non présence de ce paramètre pour la seconde règle pour qu'elle ne s'applique que dans le cas où le paramètre n'existe pas, i.e. lorsque l'utilisateur demande cette URL :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    RewriteRule ^index\.php$ /contact.php?dummy=1 [L]
    RewriteCond %{QUERY_STRING} !dummy=1
    RewriteRule ^contact\.php$ presentation.php [L]

    Du détail, du détail, du détail !!!
    Revenons à la source : lisons la documentation et les fichiers de trace, la réponse à notre problème s'y trouve sans doute

  3. #3
    Candidat au Club
    _Mac_,

    Merci infiniment pour cette réponse très précise et pour l'astuce que tu donnes. C'est de la bonne grugerie mais ca m'a l'air radical en effet.
    La doc d'apache que j'avais regardé de mon côté (http://httpd.apache.org/docs/1.3/mod...d_rewrite.html) est source de confusion. Elle dit en particulier
    "Stop the rewriting process here and don't apply any more rewriting rules. This corresponds to the Perl last command or the break command from the C language. Use this flag to prevent the currently rewritten URL from being rewritten further by following rules. ".
    .

    Il est d'ailleurs dommage à mon avis que le processus de réécriture de puisse pas être interrompu.