路由 PHP 5.4+ 内置 Web 服务器,如 .htaccess
Routing PHP 5.4+ Built-in Web Server like .htaccess
我已经开始使用 PHP 5.6 的内置 Web 服务器,使用以下命令:
php -S localhost:80
我以前用过 WAMP 服务器。并且手册还说,如果您为上述命令提供路由器脚本,请说:
php -S localhost:80 router.php
我们可以实现类似 .htaccess
的目标。但是我找不到关于如何进行重定向或包含的可靠教程。现在,我的 .htaccess
文件包含以下内容:
RewriteEngine On
RewriteRule (.*)-(.*)\.htm$ ./?page=&sub=&%{QUERY_STRING}
RewriteRule ^([^/]*)\.htm$ ./?page=&%{QUERY_STRING} [L]
我应该在 router.php
中输入什么才能获得与 Apache Web 服务器相同的输出?提前致谢。
<?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. [=10=] or
* @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=&sub=&%{QUERY_STRING}') && finalize();
test('%^([^/]*)\.htm$%') && rewrite('/?page=[=10=]&%{QUERY_STRING}') && finalize();
echo "<pre>";
var_dump($_SERVER);
// include index.php or something
我已经包含了一堆 'helper' 函数,这将使您更容易编写重写规则 (borrowed here)。
我在博客 The Reality Tunnel which referenced a blog on 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';
老问题,但这里有一个简单的版本:
<?php
/* Friendly Urls
================================================
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f [NC]
RewriteCond %{SCRIPT_FILENAME} !-d [NC]
RewriteRule ^(.+)$ /index.php?page= [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 服务器。
我已经开始使用 PHP 5.6 的内置 Web 服务器,使用以下命令:
php -S localhost:80
我以前用过 WAMP 服务器。并且手册还说,如果您为上述命令提供路由器脚本,请说:
php -S localhost:80 router.php
我们可以实现类似 .htaccess
的目标。但是我找不到关于如何进行重定向或包含的可靠教程。现在,我的 .htaccess
文件包含以下内容:
RewriteEngine On
RewriteRule (.*)-(.*)\.htm$ ./?page=&sub=&%{QUERY_STRING}
RewriteRule ^([^/]*)\.htm$ ./?page=&%{QUERY_STRING} [L]
我应该在 router.php
中输入什么才能获得与 Apache Web 服务器相同的输出?提前致谢。
<?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. [=10=] or
* @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=&sub=&%{QUERY_STRING}') && finalize();
test('%^([^/]*)\.htm$%') && rewrite('/?page=[=10=]&%{QUERY_STRING}') && finalize();
echo "<pre>";
var_dump($_SERVER);
// include index.php or something
我已经包含了一堆 'helper' 函数,这将使您更容易编写重写规则 (borrowed here)。
我在博客 The Reality Tunnel which referenced a blog on 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';
老问题,但这里有一个简单的版本:
<?php
/* Friendly Urls
================================================
RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-f [NC]
RewriteCond %{SCRIPT_FILENAME} !-d [NC]
RewriteRule ^(.+)$ /index.php?page= [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 服务器。