mod_rewrite:如何在第一场比赛后停止?

时间:2015-02-24 15:37:44

标签: .htaccess mod-rewrite

我有一个使用GET变量来确定语言的PHP应用程序,即:

http://example.com/?lang=en

我正在编写一个mod_rewrite规则,以便人们可以使用SEO友好的URL访问它:

http://example.com/en/

到目前为止,我的.htaccess看起来像这样:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[a-z]{2} /test.php?lang=$0 [L]

(test.php只是一个测试,而不是我真实应用的名称。)

但是当我访问时:

http://example.com/fr/blabla

我在rewrite_log中得到的内容如下:

192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] add path info postfix: /var/www/html/example/fr -> /var/www/html/example/fr/blabla
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] strip per-dir prefix: /var/www/html/example/fr/blabla -> fr/blabla
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) [perdir /var/www/html/example/] applying pattern '^[a-z]{2}' to uri 'fr/blabla'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (2) [perdir /var/www/html/example/] rewrite 'fr/blabla' -> '/test.php?lang=fr'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (3) split uri=/test.php?lang=fr -> uri=/test.php, args=lang=fr
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b8ce58/initial] (1) [perdir /var/www/html/example/] internal redirect with /test.php [INTERNAL REDIRECT]
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (3) [perdir /var/www/html/example/] strip per-dir prefix: /var/www/html/example/test.php -> test.php
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (3) [perdir /var/www/html/example/] applying pattern '^[a-z]{2}' to uri 'test.php'
192.168.172.1 - - [24/Feb/2015:16:30:10 +0100] [example.com/sid#896a010][rid#8b92310/initial/redir#1] (1) [perdir /var/www/html/example/] pass through /var/www/html/example/test.php

我不明白为什么,在第一次匹配(日志中的第4行)之后,mod_rewrite会一次又一次地保持匹配和重定向。我发现有几个人在这里发布了类似的问题,并且由于他们的答案,我尝试添加RewriteCond规则,但mod_rewrite似乎忽略了它(是的,test.php确实存在于我的文件系统中)。发生了什么事?

编辑:忘了提。我正在测试的服务器是Apache 2.2.3。

编辑:没关系。这是我的test.php中的一个拼写错误,它阻止它被正确执行(你能在这里添加一个“eyeroll”或“尴尬”表情符号吗?)

1 个答案:

答案 0 :(得分:1)

要在首次重写后停止,您可以使用:

RewriteEngine On

RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[a-z]{2} test.php?lang=$0 [L,QSA]

%{ENV:REDIRECT_STATUS}是内部变量,在Apache首次重写后设置为200。

但是,如果RewriteCond %{REQUEST_FILENAME} !-f 是有效文件,则test.php应在第一次重写后停止重写循环。