Php 优化mod_重写
我正在使用mod_rewrite创建规范链接。到目前为止,我已经使用RewriteRule成功地满足了每个测试用例。下面的代码肯定有效,并且可能足够了。然而,我知道这些重写可能会很费劲,所以我想让它们尽可能高效。在哪里可以提高效率?是什么使重写效率降低或低效 网站有三个不同的区域:国家、州和学校。每个区域的主页是整个区域的中心。例如,“州”提供了所有50个州的列表 州域:Php 优化mod_重写,php,apache,.htaccess,mod-rewrite,canonical-link,Php,Apache,.htaccess,Mod Rewrite,Canonical Link,我正在使用mod_rewrite创建规范链接。到目前为止,我已经使用RewriteRule成功地满足了每个测试用例。下面的代码肯定有效,并且可能足够了。然而,我知道这些重写可能会很费劲,所以我想让它们尽可能高效。在哪里可以提高效率?是什么使重写效率降低或低效 网站有三个不同的区域:国家、州和学校。每个区域的主页是整个区域的中心。例如,“州”提供了所有50个州的列表 州域: url.com/state/生成默认年份所有50个州(r=州)的列表 url.com/state/GA/生成默认年份的GA
- url.com/state/生成默认年份所有50个州(r=州)的列表
- url.com/state/GA/生成默认年份的GA(r=GA)列表
- url.com/state/2011生成了2011年(class=2011)所有50个州(r=state)的列表
- url.com/state/GA/2011生成2011年(class=2011)的GA(r=GA)列表
- url.com/national/生成默认年份的国家列表(r=national)
- url.com/national/jobs/生成默认年份的全国性工作列表(r=national)(show=jobs)
- url.com/national/2011生成2011年(class=2011)的全国性清单(r=national)
- url.com/national/jobs/2011生成2011年(class=2011)全国性工作(show=jobs)列表(r=national)
<IfModule mod_rewrite.c>
RewriteEngine on
# Rewrite user URLs
RewriteRule ^state/?$ index.php?r=state [L,NC]
RewriteRule ^state/([0-9]+)/?$ index.php?r=state&class=$1 [L,NC]
RewriteRule ^state/([A-Za-z]+)/?$ index.php?r=$1 [L,NC]
RewriteRule ^state/([A-Za-z]+)/([0-9]+)/?$ index.php?r=$1&class=$2 [L,NC]
RewriteRule ^national/?$ index.php?r=national [L,NC]
RewriteRule ^national/([0-9]+)/?$ index.php?r=national&class=$1 [L,NC]
RewriteRule ^national/([A-Za-z]+)/?$ index.php?r=national&show=$1 [L,NC]
RewriteRule ^national/([A-Za-z]+)/([0-9]+)/?$ index.php?r=national&show=$1&class=$2 [L,NC]
RewriteRule ^schools/?$ index.php?r=schools [L,NC]
RewriteRule ^schools/([0-9]+)/?$ index.php?r=schools&class=$1 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/?$ index.php?school=$1 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([0-9]+)/?$ index.php?school=$1&class=$2 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&class=$3 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC]
</IfModule>
重新启动发动机
#重写用户URL
重写规则^state/?$index.php?r=状态[L,NC]
重写规则^state/([0-9]+)/?$index.php?r=state&class=1[L,NC]
重写规则^state/([A-Za-z]+)/?$index.php?r=$1[L,NC]
重写规则^state/([A-Za-z]+)/([0-9]+)/?$index.php?r=$1&class=$2[L,NC]
重写规则^national/?$index.php?r=national[L,NC]
重写规则^national/([0-9]+)/?$index.php?r=national&class=1[L,NC]
重写规则^national/([A-Za-z]+)/?$index.php?r=national&show=1[L,NC]
重写规则^national/([A-Za-z]+)/([0-9]+)/?$index.php?r=national&show=$1&class=$2[L,NC]
重写规则^schools/?$index.php?r=学校[L,NC]
重写规则^schools/([0-9]+)/?$index.php?r=schools&class=1[L,NC]
重写规则^schools/([A-Za-z-]+)/?$index.php?school=$1[L,NC]
重写规则^schools/([A-Za-z-]+)/([0-9]+)/?$index.php?school=$1&class=$2[L,NC]
重写规则^schools/([A-Za-z-]+)/([A-Za-z]+)/?$index.php?school=$1&show=$2[L,NC]
重写规则^schools/([A-Za-z-]+)/([A-Za-z]+)/([0-9]+)/?$index.php?school=$1&show=$2&class=$3[L,NC]
重写规则^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/?$index.php?school=$1&show=$2&sub=$3[L,NC]
重写规则^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/?$index.php?school=$1&show=$2&sub=$3&class=$4[L,NC]
提前谢谢。如果其他细节有帮助,我将更新/回复。任何类型的优化都需要在php脚本中进行“空白”检查,因为不存在的路径仍将有一个与之关联的
$\u GET['']
变量,只是它将是空白的
就“国家”和“国家”URL而言,您几乎只能做一件事,将这两条规则结合起来:
RewriteRule ^state/([A-Za-z]+)/?$ index.php?r=$1 [L,NC]
RewriteRule ^state/([A-Za-z]+)/([0-9]+)/?$ index.php?r=$1&class=$2 [L,NC]
通过将“class”设置为可选(但仍将有一个“class”参数,它将为空):
与国家标准相同:
RewriteRule ^national/([A-Za-z]+)/?$ index.php?r=national&show=$1 [L,NC]
RewriteRule ^national/([A-Za-z]+)/([0-9]+)/?$ index.php?r=national&show=$1&class=$2 [L,NC]
合并为:
RewriteRule ^national/([A-Za-z]+)(?:/([0-9]+)|)/?$ index.php?r=national&show=$1&class=$2 [L,NC]
但是学校的事情要复杂一点。您可以将其中一些组合起来,例如:
RewriteRule ^schools/([A-Za-z-]+)/?$ index.php?school=$1 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC]
可以组合成一个单独的:
RewriteRule ^schools/([A-Za-z-]+)(?:/([A-Za-z]+)|)(?:/([A-Za-z]+)|)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)(?:/([A-Za-z]+)|)(?:/([A-Za-z]+)|)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC]
而
RewriteRule ^schools/([0-9]+)/?$ index.php?r=schools&class=$1 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([0-9]+)/?$ index.php?school=$1&class=$2 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&class=$3 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC]
可以组合成一个单独的:
RewriteRule ^schools/([A-Za-z-]+)(?:/([A-Za-z]+)|)(?:/([A-Za-z]+)|)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC]
RewriteRule ^schools/([A-Za-z-]+)(?:/([A-Za-z]+)|)(?:/([A-Za-z]+)|)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC]
你可以为每3个页面创建一个大的正则表达式,但是你必须测试它是否真的让事情变得更快或更慢。如果Apache必须应用更多的正则表达式才能为页面提供服务,那么速度会慢一些,但是如果它必须对url应用复杂的正则表达式,那么速度可能会慢于对同一url应用几个简单的正则表达式。Mod_rewrite的url重写速度比大多数编程语言都快,这主要是因为要重写url,不需要加载任何解释器/编译器 如果您能够使用
END
标志而不是L
标志,这将加快重写速度,因为与L
标志不同,END
标志将完全停止重写,而不仅仅是这一轮重写。但是,它在旧版本的Apache上不可用
但是,您正在将所有请求重定向到index.php,因此有如下规则:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ /index.php [L]
然后检查$\u服务器['REQUEST\u URI']
,例如:
$boom = explode( '/', $_SERVER['REQUEST_URI'] );
#var_dump( $boom ); //Something like Array( '', 'state', '2011' );
if( isset( $boom[1] ) ) {
if( $boom[1] == 'state' ) {
if( isset( $boom[3] ) ) {
$r = $boom[2];
$class = $boom[3];
} else if( isset( $boom[2] ) && intval( $boom[2], 10 ) == $boom[2] ) {
$r = 'state';
$class = $boom[2];
} else if( isset( $boom[2] ) ) {
$r = $boom[2];
} else {
$r = 'state';
}
} else if( $boom[1] == 'schools' ) {
echo 'a';
}
} else {
header( '404: What the heck is this?!' );
//No, don't use this header...
}
Rewriterule^state/([A-Za-z]+)/)([0-9]+)/)?$/index.php?r=$2&class=$4
带有强制尾随的/
应该可以解决问题,对吗?您可以对其他URL执行类似的操作。@Sumurai8的问题是,如果中间路径丢失,“r”变成“state”,这非常有用。谢谢你花时间在这件事上,乔恩。我已经测试了你的解决方案,它们工作完美无瑕。(我应该补充一点,php脚本已经为每个_GET设置了默认值,如果没有通过任何操作。)感谢您的建议,特别是L vs End建议。我将尝试确定我的apache版本是否支持End。