mod_重写以删除.php,但仍然提供.php文件?

mod_重写以删除.php,但仍然提供.php文件?,php,apache,mod-rewrite,Php,Apache,Mod Rewrite,我只想用mod_重写做一件简单的事情。我有一个使用.php文件的网站,我想将这些文件重写为更干净的URL,并删除.php文件。所以,文件应该是www.mysite.com/contact等等 这确实是我想要的,但我原以为它仍然会提供我的contact.php文件,但只是向用户显示他们在/contact,而不是contact.php。但是,它正在寻找一个名为contact的文件,而这个文件并不存在 所以,我需要做的是,仍然使用我的contact.php文件,但重写用户到/contact的URL 以

我只想用mod_重写做一件简单的事情。我有一个使用.php文件的网站,我想将这些文件重写为更干净的URL,并删除.php文件。所以,文件应该是www.mysite.com/contact等等

这确实是我想要的,但我原以为它仍然会提供我的contact.php文件,但只是向用户显示他们在/contact,而不是contact.php。但是,它正在寻找一个名为contact的文件,而这个文件并不存在

所以,我需要做的是,仍然使用我的contact.php文件,但重写用户到/contact的URL

以下是我正在使用的:

SetEnv APPLICATION_ENV development
RewriteEngine on
RewriteBase /

# Always use www.
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301]

# Change urlpath.php to urlpath
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
RewriteRule ^(.*)\.php$ http://www.mysite.com/$1 [L,R=301]

你的第三条规则应该是相反的:

# Change urlpath.php to urlpath
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]
RewriteRule ^/?(.*)$ $1.php [L,R=301]

一旦用户转到/contact,它将加载contact.php。额外的重写条件是,如果用户确实转到contact.php,它将不会尝试加载contact.php.php

,因为我知道您希望URL是/contact,即使URL是/contact.php

您可以检查.php扩展名并执行重定向以删除它。使用R=301(和您一样)

然后,您必须使服务器接受不带.php扩展名的URL。它可能已经做到了

这就是我所做的。默认情况下应该安装它,但您可能必须启用它


您也可以使用mod_rewrite来实现这一点,但是从选项中删除R。它将在内部重定向,而不是通过HTTP重定向进行应答。

对于此解决方案,我遵循以下规则:

  • 如果用户试图加载
    /something.php
    ,则应将其从外部重定向到
    /something
  • 如果用户试图加载
    /something
    ,则应在内部将其重定向到
    /something.php
  • 如果用户向URL传递了任何查询字符串参数,则应通过重定向保留这些参数
  • 如果用户试图加载文件系统中实际存在的不同文件(样式表、图像等),则应按原样加载
  • 这是最后一组mod_重写魔法:

    RewriteEngine on
    RewriteBase /
    
    ## Always use www.
    RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
    RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301]
    
    # Change urlpath.php to urlpath
    ## Only perform this rule if we're on the expected domain
    RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
    ## Don't perform this rule if we've already been redirected internally
    RewriteCond %{QUERY_STRING} !internal=1 [NC]
    ## Redirect the user externally to the non PHP URL
    RewriteRule ^(.*)\.php$ $1 [L,R=301]
    
    # if the user requests /something we need to serve the php version if it exists
    
    ## Only perform this rule if we're on the expected domain
    RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
    ## Perform this rule only if a file with this name does not exist
    RewriteCond %{REQUEST_FILENAME} !-f
    ## Perform this rule if the requested file doesn't end with '.php'
    RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]
    ## Only perform this rule if we're not requesting the index page
    RewriteCond %{REQUEST_URI} !^/$
    ## Finally, rewrite the URL internally, passing through the user's query string
    ## using the [qsa] flag along with an 'internal=1' identifier so that our first
    ## RewriteRule knows we've already redirected once.
    RewriteRule ^(.*)$ $1.php?internal=1 [L, QSA]
    

    唯一的问题是,它还重写了带有.php扩展名的图像、css等。其中的一个问题是,当访问www.mysite.com时,它不会获取index.php文件。我们需要向这个规则添加什么来确保它是目录中的索引文件呢?很好。我已经在最后一个块中添加了一个
    RewriteCond
    ,以便在请求索引页时不运行
    RewriteRule
    。添加查询参数的正确方法是使用QSA标志。感谢Fozi-我已经将最后一个
    RewriteRule
    添加到使用QSA标志。