的mod_rewrite的.htaccess造成500服务器错误,如果URL不存在不存在、错误、服务器、htaccess

2023-09-02 00:36:48 作者:放不了你丶梦

我刚刚开始使用mod_rewrite,这是我使用了一个很基本的结构化的网站,多语言支持:

I've just started using mod_rewrite, this is what I use for a quite basic structured website with multiple language support:

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变量(?LANG = EN )。

所以,为URL可能看起来像这样: / EN /指数键,然后应重定向到的index.php LANG = EN

So, an URl could look like this: /en/index and should then be redirected to index.php?lang=en.

如果该URL不是以一种语言,而是直接用字符串,那么没有的GET-变量将被附连到弦。例如。 /指数应参照的index.php 。如果没有字符串,那么索引应作为默认

If the URl does not start with a language, but directly with the string, then no GET-variable will be attached to the string. E.g. /index should refer to index.php. If there is no string, then index should be used as default.

到目前为止,一切都很好。工作正常。只是,如果我输入一个字符串(不管我用2个字符的语言或没有),该网站始终显示,而不是去 error404.php 一个500内部服务器错误, 。另外,如果我删除这一行(404)在.htaccess,它仍然是同样的错误。

So far, so good. Works fine. Just if I enter a string (no matter if I use 2 characters for language or not), the site always shows an 500 Internal Server Error, instead of going to error404.php. Also, if I delete this line (404) in .htaccess, it is still the same error.

所以,我认为有一些错误,在导致此错误的.htaccess中的其他行,没有任何人有一个想法是什么,这可能是?

So, I assume that there is something wrong with the other lines in the .htaccess that cause this error, does anybody have an idea what this could be?

任何帮助是非常AP preciated!

Any help is highly appreciated!

推荐答案

您规则的循环。一目了然,它看起来像你的最后一个:

Your rules are looping. At a glance, it looks like your last one:

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

说我有这个URL, http://your.domain.com/blah ,文件 blah.php 不存在。这是发生了什么。

Say I have this URL, http://your.domain.com/blah, and the file blah.php doesn't exist. This is what's happening.

URI = 等等,!-f是真实的,它不是一个文件 URI = 等等,!-d是真实的,它不是一个目录 URI = 等等,内部重写 blah.php 等等!= blah.php ,重写规则回路 URI = blah.php !-f是真实的,它不是一个文件 URI = blah.php !-d是真实的,它不是一个目录 URI = blah.php ,内部重写 blah.php.php blah.php != blah.php.php ,重写规则回路 URI = blah, !-f is true, it's not a file URI = blah, !-d is true, it's not a directory URI = blah, internal rewrite to blah.php blah != blah.php, rewrite rules loop URI = blah.php !-f is true, it's not a file URI = blah.php !-d is true, it's not a directory URI = blah.php, internal rewrite to blah.php.php blah.php != blah.php.php, rewrite rules loop

这一直持续到重写引擎已经受够了,并返回一个500服务器错误。

This goes on until the rewrite engine has had enough and returns a 500 server error.

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

You can do one of 2 things here:

添加指令,使所有循环停止不管什么,这是一个容易解决这种东西。但它会破坏那些需要循环的规则。我没有看到这样的规则中的任何东西所以它是安全的(至少目前如此),要做到这一点。只需将它添加到您的规则上:

Add a directive to make all looping stop no matter what, which is an easy to get around this kind of stuff. But it will break rules that require looping. I don't see anything like that in your rules so it's safe (at least for now) to do this. Just add this to the top of your rules:

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

做一个pre-先发制人的检查,以查看PHP文件确实存在:

Do a pre-emptive check to see if the php file actually exists:

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