如何在PHP中模拟mod_重写

如何在PHP中模拟mod_重写,php,apache,mod-rewrite,redirect,Php,Apache,Mod Rewrite,Redirect,我有一些URL,我想通过PHP映射到某些文件。目前,我只是在Apache中使用mod_rewrite。但是,我的应用程序变得太大,无法用正则表达式进行重写。因此,我创建了一个文件router.php,用于重写。我知道要重定向,我可以发送位置:标题。然而,我并不总是想做重定向。例如,我可能希望/api/item/映射到相对于文档根的文件/herp/derp.php。我还需要保留HTTP方法。“没问题,”我想。我让我的.htaccess有以下代码片段 RewriteEngine On Rewrite

我有一些URL,我想通过PHP映射到某些文件。目前,我只是在Apache中使用mod_rewrite。但是,我的应用程序变得太大,无法用正则表达式进行重写。因此,我创建了一个文件
router.php
,用于重写。我知道要重定向,我可以发送
位置:
标题。然而,我并不总是想做重定向。例如,我可能希望
/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);

?>

将.htaccess更改为read

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"

将.htaccess更改为read

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"

请尝试使用
文件获取内容,而不是
要求一次

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

编辑

对于记录,如果您需要使用任何方法(HTTP、HTTPS、FTP等)或页面信息(如Cookie),您可以将其用作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
);

请尝试使用
文件获取内容,而不是
要求一次

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

编辑

对于记录,如果您需要使用任何方法(HTTP、HTTPS、FTP等)或页面信息(如Cookie),您可以将其用作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
);

您不需要附加查询,它已经在那里了。。。只是
require\u once“{$\u SERVER['DOCUMENT\u ROOT']}/herp/derp.php”
对不起,刚刚做了一次编辑。实际上,我正在根据请求的URL修改查询。我忘了把细节放在那里了。那就修改一下吧<代码>$\u GET['some\u var']='my modifications'啊。现在我觉得自己很愚蠢。太明显了。哈如果你发布答案,我会接受。你不需要附加查询,它已经在那里了。。。只是
require\u once“{$\u SERVER['DOCUMENT\u ROOT']}/herp/derp.php”
对不起,刚刚做了一次编辑。实际上,我正在根据请求的URL修改查询。我忘了把细节放在那里了。那就修改一下吧<代码>$\u GET['some\u var']='my modifications'啊。现在我觉得自己很愚蠢。太明显了。哈如果你发布一个答案,我会接受。如果Apache没有修改查询,
QSA
标志在这种情况下真的有必要吗?@TylerCrompton no它没有。。。但是如果您确实更新了它以传递url来确定请求的页面,而不是使用php
RewriteCond%{REQUEST_URI}^api/RewriteRule^(.*)$/cgi-bin/router.php?url=$1
然后您将保留查询。。。我总是喜欢添加
QSA
标志,在这种情况下,如果Apache没有修改查询,那么这是非常必要的?@TylerCrompton no it not。。。但是如果您确实更新了它以传递url来确定请求的页面,而不是使用php
RewriteCond%{REQUEST_URI}^api/RewriteRule^(.*)$/cgi-bin/router.php?url=$1
然后您将保留查询。。。我总是喜欢添加它,虽然这样做会使请求数量增加一倍(并且不会保留原始url中的任何标题或数据,即没有会话持久性、cookie信息或POST数据),但总体而言,使用这种方法不是一个好主意。对于POST、PUT或DELETE方法,它根本不起作用。如果我想这样做,我就用cURL。但同样@Edakos,这个问题不需要额外的请求。这个答案适用于任何方法?您不需要处理加倍的请求=)虽然这样做会使请求数加倍(并且不会保留原始url中的任何标题或数据,即没有会话持久性、cookie信息或POST数据),但总体而言,使用这种方法不是一个好主意,因为对于POST、PUT或DELETE方法根本不起作用。如果我想这样做,我就用cURL。但同样@Edakos,这个问题不需要额外的请求。这个答案适用于任何方法?您不处理加倍请求=)