Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 优化mod_重写_Php_Apache_.htaccess_Mod Rewrite_Canonical Link - Fatal编程技术网

Php 优化mod_重写

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

我正在使用mod_rewrite创建规范链接。到目前为止,我已经使用RewriteRule成功地满足了每个测试用例。下面的代码肯定有效,并且可能足够了。然而,我知道这些重写可能会很费劲,所以我想让它们尽可能高效。在哪里可以提高效率?是什么使重写效率降低或低效

网站有三个不同的区域:国家、州和学校。每个区域的主页是整个区域的中心。例如,“州”提供了所有50个州的列表

州域:

  • 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。