如何在PHP中模拟mod_rewrite

时间:2013-10-23 15:17:14

标签: php apache mod-rewrite redirect

我有几个网址要通过PHP映射到某些文件。目前,我只是在Apache中使用mod_rewrite。但是,我的应用程序变得太大,无法使用正则表达式进行重写。所以我创建了一个文件router.php来进行重写。我理解做重定向我可以发送Location:标题。但是,我并不总是想要重定向。例如,我可能希望/api/item/映射到相对于文档根目录的文件/herp/derp.php。我还需要保留HTTP方法。 "没问题,"我想。我让我的.htaccess有以下代码段。

RewriteEngine On
RewriteRule ^api/item/$ /cgi-bin/router.php [L]

我的router.php文件如下所示:

<?php

$uri = parse_url($_SERVER['REQUEST_URI']);
$query = isset($uri['query']) ? $uri['query'] ? array();
// some code that modifies the query
require_once "{$_SERVER['DOCUMENT_ROOT']}/herp/derp.php?" . http_build_query($query);

?>

但是,这不起作用,因为操作系统正在寻找名为derp.php?some=query的文件。如何在PHP中模拟重写规则,例如RewriteRule ^api/item/$ /herp/derp/ [L]。换句话说,如何告诉服务器处理与请求不同的URL并保留查询和HTTP方法而不会导致重定向?

注意:使用router.php中设置的变量不太理想,结构不好,因为它只应该负责处理URL。我愿意使用轻量级的第三方解决方案。

2 个答案:

答案 0 :(得分:1)

将.htaccess更改为

RewriteEngine On
RewriteRule ^api/item/$ /cgi-bin/router.php [QSA,L]

在你的php中

// update your get variables
$_GET['some_var'] = 'my modifications';

// require file
require_once "{$_SERVER['DOCUMENT_ROOT']}/herp/derp.php"

答案 1 :(得分:0)

而不是require_once,请尝试file_get_contents

file_get_contents ((stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://'). "{$_SERVER['SERVER_NAME']}/herp/derp.php?" . http_build_query($query));

小心SERVER_NAME

修改

对于记录,如果您需要使用任何方法(HTTP,HTTPS,FTP等)或页面信息(如cookie),您可以使用streams作为内置(更快?)替代方案cURL和PECL。在这个例子中:

$params = array(
   'http' => array(
      'method' => 'GET',
      'content' => http_build_query($query)
   )
);

$context = stream_context_create($params);

file_get_contents (
   (stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://'). "{$_SERVER['SERVER_NAME']}/herp/derp.php", 
   false, 
   $context
);