如果URl不存在,则mod_rewrite .htaccess导致500服务器错误

时间:2012-09-17 12:59:09

标签: php .htaccess mod-rewrite webserver

我刚刚开始使用mod_rewrite,这是我用于具有多种语言支持的非常基本的结构化网站:

RewriteEngine on
ErrorDocument 404 /error404.php

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/([^/]+)$ $2.php?lang=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/$ index.php?lang=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})$ index.php?lang=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ $1.php [L]

我的想法是语言在URl的开头指示,需要是两个字符(a-z或A-Z)。之后会有一个字符串引用一个php文件,该文件与字符串具有相同的文件名,只附加.php。该语言将作为GET变量(?lang=en)添加。

因此,URl可能如下所示:/en/index然后应重定向到index.php?lang=en

如果URl不是以语言开头,而是直接使用字符串,则不会将任何GET变量附加到字符串。例如。 /index应该引用index.php。如果没有字符串,则应使用index作为默认值。

到目前为止,这么好。工作良好。只要我输入一个字符串(无论我是否使用2个字符作为语言),该站点始终显示500内部服务器错误,而不是转到error404.php。此外,如果我在.htaccess中删除此行(404),则仍然是相同的错误。

所以,我认为.htaccess中导致此错误的其他行有问题,是否有人知道这可能是什么?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

您的规则正在循环播放。乍一看,它看起来像是你的最后一个:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)$ $1.php [L]

假设我有此网址http://your.domain.com/blah,并且文件blah.php不存在。这就是发生的事情。

  1. URI = blah,! - f为true,它不是文件
  2. URI = blah,! - d为true,它不是目录
  3. URI = blah,内部重写为blah.php
  4. blah!= blah.php,重写规则循环
  5. URI = blah.php! - f为true,它不是文件
  6. URI = blah.php!-d为true,它不是目录
  7. URI = blah.php,内部重写为blah.php.php
  8. blah.php!= blah.php.php,重写规则循环
  9. 这一直持续到重写引擎已经足够并返回500服务器错误。

    你可以在这里做两件事之一:

    1. 添加一个指令,使所有循环停止,无论什么,这很容易解决这类问题。但它会破坏需要循环的规则。我在你的规则中没有看到这样的东西,所以这样做是安全的(至少现在是这样)。只需将其添加到规则的顶部:

      RewriteCond %{ENV:REDIRECT_STATUS} 200
      RewriteRule ^ - [L]
      
    2. 进行先发制人的检查以查看php文件是否确实存在:

      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteCond %{REQUEST_FILENAME}.php -f
      RewriteRule ^([^/]+)$ $1.php [L]
      

答案 1 :(得分:1)

Helmut,试试这个(最后一条规则是500内部错误的原因,这也包括@DaveRandom合并规则2和3的建议):

RewriteEngine on
ErrorDocument 404 /error404.php

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/([^/]+)$ $2.php?lang=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z]{2})/?$ index.php?lang=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9]+)$ $1.php [L]