2015-01-04 42 views
2

:前路由PHP 5.4+内置Web服务器就像我已经使用PHP 5.6的内置使用以下命令web服务器启动的.htaccess

php -S localhost:80 

我使用WAMP服务器。和手动也说,如果你给一个路由器脚本上面的命令,说这样的:

php -S localhost:80 router.php 

我们可以实现类似.htaccess。但是我无法找到一个可靠的教程来了解如何进行重定向或包含。现在,我的.htaccess文件中有这样的内容:

RewriteEngine On 
RewriteRule (.*)-(.*)\.htm$ ./?page=$1&sub=$2&%{QUERY_STRING} 
RewriteRule ^([^/]*)\.htm$ ./?page=$1&%{QUERY_STRING} [L] 

那我就摆在router.php为了实现我不得不在Apache Web服务器相同的输出?提前致谢。

+1

请参阅[mod_rewrite.php](https://github.com/markkimsal/nanoweb-ssl/blob/master/modules/mod_rewrite.php)。尽管在路由器脚本中重新实现两行正则表达式来适应'REQUEST_URI' +'QUERY_STRING'肯定会更简单。 – mario 2015-01-04 13:22:01

回答

2
<?php 
    $_matches = array(); 

    /** 
    * Initialize the rewrite environment. 
    */ 
    function initialize() { 
     set_environment($_SERVER['REQUEST_URI']); 
    } 

    /** 
    * Set important environment variables and re-parse the query string. 
    * @return boolean 
    */ 
    function finalize() { 
     if (defined('REWRITER_FINALIZED')) return false; 

     define('REWRITER_FINALIZED', true); 

     if (\is_file($_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME'])) { 
      $_SERVER['SCRIPT_FILENAME'] = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_NAME']; 
     } 

     if (isset($_SERVER['QUERY_STRING'])) { 
      $_GET = []; 
      parse_str($_SERVER['QUERY_STRING'], $_GET); 
     } 

     $_SERVER['PHP_SELF'] = $_SERVER['SCRIPT_NAME']; 

     return true; 
    } 

    /** 
    * Adjust the server environment variables to match a given URL. 
    * @param string $url 
    */ 
    function set_environment($url) { 
     $url = rtrim($url, '&?'); 
     $request_uri = $script_name = $url; 
     $query_string = null; 

     if (strpos($url, '?') > 0) { 
      $script_name = substr($url, 0, strpos($url, '?')); 
      $query_string = substr($url, 1 + strpos($url, '?')); 
     } 

     $_SERVER['REQUEST_URI'] = $request_uri; 
     $_SERVER['SCRIPT_NAME'] = $script_name; 
     $_SERVER['QUERY_STRING'] = $query_string; 
    } 

    /** 
    * Parse regular expression matches. eg. $0 or $1 
    * @param string $url 
    * @return string 
    */ 
    function parse_matches($url) {   
     $replace = function($bit) { 
      global $matches; 
      return isset($matches[$bit[1]]) 
       ? $matches[$bit[1]] 
       : null; 
     }; 

     return preg_replace_callback('/\$([0-9]+)/', $replace, $url); 
    } 

    /** 
    * Parse Apache style rewrite parameters. eg. %{QUERY_STRING} 
    * @param string $url 
    * @return string 
    */ 
    function parse_parameters($url) { 
     $replace = function($bit) { 
      return isset($_SERVER[$bit[1]]) 
       ? $_SERVER[$bit[1]] 
       : null; 
     }; 
     return preg_replace_callback('/%\{([A-Z_+]+)\}/', $replace, $url); 
    } 

    /** 
    * Change the internal url to a different url. 
    * @param string $from Regular expression to match current url, or optional when used in conjunction with `test`. 
    * @param string $to URL to redirect to. 
    * @return boolean 
    */ 
    function rewrite($from, $to = null) { 
     if (defined('REWRITER_FINALIZED')) return false; 

     $url = $_SERVER['SCRIPT_NAME']; 

     if (isset($to)) { 
      $url = preg_replace($from, $to, $url); 
     } else { 
      $url = parse_matches($from); 
     } 

     set_environment(
      parse_parameters($url) 
     ); 

     return true; 
    } 

    /** 
    * Compare a regular expression against the current request, store the matches for later use. 
    * @return boolean 
    */ 
    function test($expression) { 
     global $matches; 
     if (defined('REWRITER_FINALIZED')) return false; 
     return 0 < (integer)preg_match($expression, $_SERVER['SCRIPT_NAME'], $matches); 
    } 

    initialize(); 

    // Your rewrite rules here. 
    test('%/(.*)-(.*)\.htm$%') && rewrite('/?page=$1&sub=$2&%{QUERY_STRING}') && finalize(); 
    test('%^([^/]*)\.htm$%') && rewrite('/?page=$0&%{QUERY_STRING}') && finalize(); 

    echo "<pre>"; 
    var_dump($_SERVER); 
    // include index.php or something 

我已经包含了一堆的“帮手”功能,这将使它更容易写你重写规则(borrowed here)。

+0

让我尝试这个......':))' – 2015-01-04 14:12:51

+0

嗨@Bjorn,我试着'var_dump($ _ GET);'在脚本结尾。它似乎没有工作,或者我想我做错了什么。你能指导并解释我在哪里做什么?同时,我也会尝试破译你的脚本! – 2015-01-04 14:21:10

+0

嗯,什么不工作?如果我运行服务器'php -S localhost:8000 router.php',在我的浏览器中打开'http:// localhost:8000/foo-bar.htm',当'page = foo,sub = bar'时我'var_dump($ _ GET)'。如果你想让'/foo-bar.html?moo'工作,我发现我在重写时犯了一个小错误。在'%{QUERY_STRING}'之前添加一个'&'来修复它。 – Bjorn 2015-01-04 14:24:17

1

我在博客The Reality Tunnel上发现了一篇教程,其中引用了包含路由器脚本的博客Ripeworks

他们给路由器脚本

<?php 

$root = $_SERVER['DOCUMENT_ROOT']; 
chdir($root); 
$path = '/'.ltrim(parse_url($_SERVER['REQUEST_URI'])['path'],'/'); 
set_include_path(get_include_path().':'.__DIR__); 
if(file_exists($root.$path)) 
{ 
    if(is_dir($root.$path) && substr($path,strlen($path) - 1, 1) !== '/') 
     $path = rtrim($path,'/').'/index.php'; 
    if(strpos($path,'.php') === false) return false; 
    else { 
     chdir(dirname($root.$path)); 
     require_once $root.$path; 
    } 
}else include_once 'index.php'; 
1

老问题,但这里是一个简单的版本:

<?php 
    /* Friendly Urls 
     ================================================ 
     RewriteEngine On 
     RewriteCond %{SCRIPT_FILENAME} !-f [NC] 
     RewriteCond %{SCRIPT_FILENAME} !-d [NC] 
     RewriteRule ^(.+)$ /index.php?page=$1 [QSA,L] 
     ================================================ */ 

    $root=__dir__; 

    $uri=parse_url($_SERVER['REQUEST_URI'])['path']; 
    $page=trim($uri,'/'); 

    if (file_exists("$root/$page") && is_file("$root/$page")) { 
     return false; // serve the requested resource as-is. 
     exit; 
    } 

    $_GET['page']=$page; 
    require_once 'index.php'; 
?> 

这样,您就可以使用您可能已经有使用普通index.php,说,一个Apache服务器。

+0

最简单的答案呢。谢谢! – 2017-10-22 01:30:53