如何在PHP中使用Apache RewriteMap?

时间:2016-05-31 06:36:52

标签: php apache .htaccess mod-rewrite url-rewriting

我一直在考虑使用RewriteMap来动态处理一系列网址重写,而我想要做的是使用PHP脚本生成适当的重写条件和规则 - - 但我无法让它发挥作用。

我已经在使用WebHost Manager和cPanel的Linux服务器上运行Apache。

我将以下内容添加到WHM> Apache配置>包含编辑器> PreVirtual Host Include>所有版本:

RewriteMap myrules "prg:/usr/lib/php /path/to/my/script.php"

我更新了配置文件,Apache重新启动好了。

现在我想调用我从.htaccess文件中定义的RewriteMap来执行重写,但这就是我被卡住的地方,一切似乎都破了。

我想抓取传入的域,在地图上检查它,然后返回关联的域:user_name值。类似的东西:

RewriteCond %{HTTP_HOST} ^(www\.)?${myrules:%{HTTP_HOST}}\.com$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com/user/${myrules:%{HTTP_HOST}}/$1 [NC,P,L]

所以,例如,如果我的地图有johnsmith.com:john-smith,那么传入的URL johnsmith.com将代理mywebsite.com/user/john-smith /的内容。

首先,我很确定上面的条件/规则都是错误的。

正确的做法是我的首要任务。

其次,如何使用RewriteMap定义的PHP脚本输出我的地图?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

johnsmith.com首先解析您的服务器了吗?如果johnsmith.com和mywebsite.com由同一台服务器处理,则无需代理请求。

我认为你的规则应该更像这样:

RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+\.com)$ [NC]
RewriteRule ^.*$ http://mywebsite.com/user/${myrules:%1}/$0 [NC,P,L]
# or
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+\.com)$ [NC]
RewriteRule ^ - [E=MAPTO:${myrules:%1}]
RewriteCond %{ENV:MAPTO} !=""
RewriteRule ^.*$ http://mywebsite.com/user/%{ENV:MAPTO}/$0 [NC,P,L]

注意:

  • $0是与RewriteRule模式匹配的整个字符串(如果.htaccess在您的DocumentRoot中,$0%{REQUEST_URI}相同)
  • %1是与最后一个RewriteCond的第一个捕获括号匹配的字符串(因此,Host头的值没有潜在的前缀“www。”)

在第二组规则中,第一个规则将“RewriteMap调用”的结果放在一个名为MAPTO的环境变量中。第二个,旨在忽略未知/未映射的主机(MAPTO值为空字符串)。

将一个PHP代码说明为RewriteMap:

<?php
$map = [
    'foo.com' => 'bar',
    'johnsmith.com' => 'john-smith',
];

if (!defined('STDOUT'))
    define('STDOUT', fopen('php://stdout', 'w'));
if (!defined('STDIN'))
    define('STDIN', fopen('php://stdin', 'r'));
set_file_buffer(STDOUT, 0);
while (!feof(STDIN)) {
    $input = rtrim(fgets(STDIN), "\n");
    fputs(STDOUT, (array_key_exists($input, $map) ? $map[$input] : 'NULL') . "\n");
}

注意:'NULL'值是Apache期望知道何时值未映射到另一个值的字符串。它允许您在Apache级别定义自己的默认值。例如:要将“root”作为后备,请使用以下语法:${myrules:%1|root}