2

我刚刚开始使用 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 的开头指示并且需要是两个字符(az 或 AZ)。之后会有一个字符串引用一个 php 文件,该文件与该字符串具有相同的文件名,只是附加了 .php。语言将作为 GET-Variable ( ?lang=en) 添加。

所以,一个 URl 可能看起来像这样:/en/index然后应该被重定向到index.php?lang=en.

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

到现在为止还挺好。工作正常。只要我输入一个字符串(无论我是否使用 2 个字符作为语言),该站点总是显示 500 Internal Server Error,而不是转到error404.php. 另外,如果我在.htaccess 中删除这一行(404),它仍然是同样的错误。

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

非常感谢任何帮助!

4

2 回答 2

3

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

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

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

  1. URI = blah, !-f 为真,它不是文件
  2. URI = blah, !-d 为真,它不是目录
  3. URI = blah,内部重写为blah.php
  4. blah!= blah.php,重写规则循环
  5. URI = blah.php!-f 为真,它不是文件
  6. URI = blah.php!-d 为真,它不是目录
  7. URI = blah.php,内部重写为blah.php.php
  8. blah.php!= blah.php.php,重写规则循环

这一直持续到重写引擎受够并返回 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]
    
于 2012-09-17T16:45:48.453 回答
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]
于 2012-09-17T16:44:19.707 回答