使用.htaccess强制删除index.php

时间:2011-06-08 07:36:28

标签: .htaccess codeigniter codeigniter-url

我目前正在使用以下内容重写http://www.site.com/index.php/test/以便直接使用http://www.site.com/test/,但我想不仅允许第二个版本,我想FORCE第二个版本。如果用户转到http://www.site.com/index.php/test/,则应立即将其重新路由到http://www.site.com/test/。 index.php永远不会出现在网址中。规定:这应该只适用于第一个index.php。如果我有一个像http://www.site.com/index.php/2011/06/08/remove-index.php-from-urls/这样的标题,它应该留下第二个index.php,因为它是URL的一部分。

允许但不强制的当前规则:     #Remove index.php     RewriteCond $ 1!^(index.php | images | css | js | robots.txt)     RewriteRule ^(。*)$ / index.php/$1 [L]

感谢。

2 个答案:

答案 0 :(得分:3)

首先(和错误)回答 - 见下文

您可以使用这些指令完成重定向(按此顺序):

RewriteCond %{REQUEST_URI} ^index.php
RewriteRule ^index\.php/(.+)$ /$1 [R,L]

RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*?)$ /index.php/$1 [L]

首先将以index.php开头的所有请求重定向到相应的缩短网址,然后使用第二条规则静默提供index.php/etc

编辑 - 请继续阅读!

实际上,上面的解决方案会生成无限重定向循环,因为Apache采取了以下操作(假设我们请求/index.php/abc):

  1. 首先RewriteCond匹配
  2. Apache重定向[R],即生成新的HTTP请求,发送到/abc
  3. /abc首先失败RewriteCond
  4. /abc匹配第二个RewriteCond
  5. Apache不会重定向,但会将此URI(因此它生成“隐藏”请求)重写为/index.php/abc。我们再次处于第1点,这是一个循环。
  6. 请注意......

    • 通过使用[L](最后一条规则)标志,我们只能告诉Apache不要处理更多重写规则,但仅限于当前规则匹配。由于发出了新的HTTP请求,因此没有关于我们如何重定向的信息。所以,任何时候两个匹配中的一个,并且无论如何它都会生成一个新请求(=>循环)
    • 使用[C](链规则)标志有点没有意义,因为它只在前一条规则匹配时才使Apache进程成为规则,而我们所拥有的两条规则是相互排除的。
    • 使用规则#1上的[NS](不是子请求)标志也不是一个选项,因为它只适用于我们的情况(请参阅Apache RewriteRule docs关于它)
    • 设置env变量不是一个选项(唉),因为在pt 2发出了一个新请求,因此破坏了我们设置的所有环境变量。

    另一种解决方案可以是重写,例如/abc/index.php?path=abc。这是由这些规则完成的(请在添加之前删除RedirectMatch类似规则):

    RedirectMatch ^/index\.php(/.*) $1
    
    RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
    RewriteRule ^(.+) /index.php?path=$1 [L,QSA]
    

    我不知道CodeIgniter脚本的内部,但是作为大多数MVC脚本,它将读取$_REQUEST['PATH_INFO']以了解请求的页面。您可以稍微修改识别页面的代码(我假设页面路径存储在$page var中):

    $page = $_REQUEST['PATH_INFO'];
    if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line
    

    这不会破坏之前的代码并完成您的要求。

答案 1 :(得分:2)

正如您所写的,如果用户转到http://www.site.com/index.php/test/,此规则会立即将他重新路由到http://www.site.com/test/

RedirectMatch 301 /index.php/(.*)/$ /$1

我不确定这是否是您所需要的,因为您当前的重写规则与我的相反。