Zend Framework / index / redirect通过htaccess来避免内容重复

时间:2012-02-12 13:35:37

标签: php apache zend-framework .htaccess mod-rewrite

我想知道是否可以向我的ZF应用的htaccess添加规则,以将以/index/段结尾的所有网址(例如http://domain.ext/index/)重定向到相同的网址没有/index/后缀。

我尝试过这个简单的规则:

RedirectMatch ^(.*)/(index(/)?)$ http://localhost$1

但它没有按预期工作(与其他框架如FuelPHP一样,它就像魅力一样)。

我知道这可以通过PHP使用插件来完成,但我想通过Apache进行重定向以提高应用程序的性能。

4 个答案:

答案 0 :(得分:2)

我不知道为什么没有人跳进去,这不是那么复杂?

配置文件从上到下执行,某些规则会立即退出。如果规则定义了外部重定向,则服务器将立即执行该重定向,因此将忽略所有后续规则。如果重定向返回到相同的服务器和配置文件,那么它只是一个带有规则的新游戏!如果重定向规则不再适用,则它将继续执行下一个规则。如果规则仍然适用,你会得到一个循环。

匹配的RewriteRule与[L]类似。 L表示“停止重写过程,不再应用任何重写规则”。这句话直接来自manual

现在您只需要按照您想要应用某些规则的顺序定义一些逻辑。您对任何/ index / path的RedirectMatch的请求肯定是您希望在配置顶部很早就有的。如果匹配,您的配置将在此处结束并执行重定向!浏览器将发送一个新请求,我们有一个新游戏。

对index.php的RewriteRule是我们将在底部添加的东西。它可能是我们的最后手段,如果如果所有失败那么规则。如果这是Zend Framework或您通过index.php或其他脚本漏斗的任何其他应用程序,我无所谓。

以下规则应涵盖索引的任何变体,包括.php,.htm和.html,最后触发ZF应用程序的index.php文件。

RedirectMatch ^(/.*)/(index.(php|html|htm)|index)/?$ $1 

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]

测试重定向规则时,请小心使用浏览器并使用可以完全重置所有缓存和历史记录设置的规则。所有当前的浏览器都在“记住”重定向方面臭名昭着。如果他们学会了重定向规则,他们将执行内部重定向,即他们不会去服务器看看有什么新内容!

答案 1 :(得分:0)

这是你的规则集可读的

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR] 
RewriteCond %{REQUEST_FILENAME} -d 
RedirectMatch ^(.*)/(index(/)?)$ http://localhost$1 
RewriteRule ^.*$                 -                        [NC,L] 
RewriteRule ^.*$                 index.php                [NC,L]

RedirectMatch是一个mod_alias指令,用于从其规则中切断conds。另外,不要混淆mod_alias和mod_rewrite指令,所以请尝试:

RewriteEngine On 
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR] 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^                   -                        [L] 

RewriteRule ^(.*?)/index/?$     $1                       [R=301,L] 

RewriteRule ^.*$                index.php                [NC,L]

(更新后海报评论)

更多脚注

我在my VM上尝试了这个,这反映了我的托管服务,但是拥有root权限我可以看到'生产'重写日志。这失败了,因为第二条规则仍然属于规则(3),后者将分派给index.php。然后返回完整内容但具有301状态并且不发布新位置。如果我将[R=301]更改为[R=301,L],那么它可以正常工作,因为服务器现在发出带有Location标题的301,并且浏览器现在会重新使用新位置。

The documentation州:

  

您几乎总是希望将[R]与[L]结合使用(即使用[R,L]),因为[R]标志本身在http://thishost[:thisport]前面加上URI,但随后将其传递给规则集中的下一个规则,这通常会导致“请求中的URI无效”警告。

答案 2 :(得分:0)

我用这个(可怕的)解决方法解决了我的问题: - 我将IndexController的“索引”动作重命名为“home” - 我为主页设置了静态路由(source) - 我把htaccess更改为:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^(.*)home(/)?$ $1 [R=301,L]
RewriteRule ^(.*)index/(.*)$ $1$2 [R=301,L]
RewriteRule ^.*$ index.php [QSA,NC,L]

所以现在主页不重复,因为http://localhost/home/被重定向到基本域而其他控制器被重定向到索引操作,如果它被调用则指定动作名称(/ controller / index / param / value)是重定向到所需的URL(/ controller / param / value /)

答案 3 :(得分:0)

RewriteRule ^(.*)/index(?|$)$ $1$2 [R=301,L]

这适用于网址

/index => /
/index?page=2 => /?page2
/index/index => /
/index/index?page=2 /?page2

你需要删除之前的尾随斜杠,对于像/ index /,index / index /

这样的url
RewriteRule ^(.*)/$ /$1 [L,R=301]

url like / index / help将无需更改即可使用