mod-rewrite 可以用来设置环境变量吗?

mod-rewrite 可以用来设置环境变量吗?

我有一个现有的简单重写规则,如下所示:

<Directory /path>
    RewriteEngine on
    RewriteBase /

    # if the requested resource does not exist
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # route the uri to a front controller
    RewriteRule ^(.*)$ index.php/$1 [L]
 </Directory>

这很好,但我想做以下两件事之一。在检测客户端 accept-language 标头的基础上,我想

(i)将检测到的语言设置为脚本可以使用的环境变量或

(ii)重写请求,使 URL 以语言代码开头(例如 www.example.com/en/some/resource)

为了实现(i),我定义了以下规则:

<Directory /path>
    RewriteEngine on
    RewriteBase /

    # if the requested resource does not exist
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d

    # if the users preferred language is supported...
    RewriteCond %{HTTP:Accept-Language} ^.*(de|es|fr|it|ja|ru|en).*$ [NC]
    # define an environmental variable PREFER_LANG
    RewriteRule ^(.*)$ - [env=PREFER_LANG:%1]    

    # route the uri to a front controller
    RewriteRule ^(.*)$ index.php/$1 [L]
 </Directory>

我尝试了几种变化,但 PREFER_LANG 没有在 $_SERVER 中定义,也无法通过 getenv 检索。

关于实施 (ii)... 只能说它很混乱。如果我找不到答案,我会发布它。

有人能给我建议吗?谢谢!

答案1

当然可以使用来设置环境变量mod_rewrite。使用以下配置:

RewriteEngine on
RewriteLog /var/log/httpd/rewrite.log
RewriteLogLevel 5

# if the requested resource does not exist
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# if the users preferred language is supported...
RewriteCond %{HTTP:Accept-Language} ^.*(de|es|fr|it|ja|ru|en).*$ [NC]
# define an environmental variable PREFER_LANG
RewriteRule ^(.*)$ - [env=PREFER_LANG:%1]    

# route the uri to a front controller
RewriteRule ^(.*)$ /cgi-bin/serverfault.cgi?q=$1 [PT]

其中,serverfault.cgi只是一个调用的 shell 脚本env。它工作得很好:

$ curl -s -H 'Accept-language: de' http://localhost/serverfault/somefile |
grep PREFER
PREFER_LANG=de

RewriteLog看起来怎么样?你应该看到类似这样的内容:

init rewrite engine with requested uri /serverfault/foo.html
applying pattern '^(.*)$' to uri '/serverfault/foo.html'
RewriteCond: input='/serverfault/foo.html' pattern='!-f' => matched
RewriteCond: input='/serverfault/foo.html' pattern='!-d' => matched
RewriteCond: input='en-US,en;q=0.8' pattern='^.*(de|es|fr|it|ja|ru|en).*$' [NC] => matched
setting env variable 'PREFER_LANG' to 'en'
applying pattern '^(.*)$' to uri '/serverfault/foo.html'
rewrite '/serverfault/foo.html' -> '/cgi-bin/serverfault.cgi?q=/serverfault/foo.html'
split uri=/cgi-bin/serverfault.cgi?q=/serverfault/foo.html -> uri=/cgi-bin/serverfault.cgi, args=q=/serverfault/foo.html
forcing '/cgi-bin/serverfault.cgi' to get passed through to next API URI-to-filename handler

答案2

根据评论PHP 手册有可能。PHP 是作为模块还是 CGI 集成的?

相关内容