Apache:如何在没有文件扩展名的情况下重写URL并忽略大小写


Apache: How to rewrite URL with no file extension and ignore case?

我正在运行带有Apache 2.2.22和PHP 5.3.10的Ubuntu 12.04。我希望用户能够在我的网站上请求页面,而不必键入".php"扩展名,也不必担心区分大小写。例如,像这样的URL。。。

http://www.site.com/test/phpinfo
http://www.site.com/test/PhPiNfO

两者都应该导致:

http://www.site.com/test/phpinfo.php

我从不区分大小写开始,遵循这个问题的公认答案。以下是我的"/etc/apache2/sites-available/default"文件的样子。。。

<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www
        RewriteMap lc int:tolower
        <Directory />
                Options FollowSymLinks
                AllowOverride All
        </Directory>
        <Directory /var/www/>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
        <Directory /var/www/test>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        </Directory>
        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>
        ErrorLog ${APACHE_LOG_DIR}/error.log
        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined
    Alias /doc/ "/usr/share/doc/"
    <Directory "/usr/share/doc/">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order deny,allow
        Deny from all
        Allow from 127.0.0.0/255.0.0.0 ::1/128
    </Directory>
</VirtualHost>

这是我的.htaccess文件:

RewriteEngine On
RewriteRule ^([a-z]+)/([a-z'-]+)$ /${lc:$1}/${lc:$2}.php [L,NC]

文件扩展名部分正在工作,但由于某些原因,仍在强制执行区分大小写。我的Apache错误日志中充满了这样的行:

[Sat Jan 05 23:10:41 2013] [error] [client 192.168.1.9] File does not exist: /var/www/test/phpinfO

你知道我在这里做错了什么吗?

编辑:经过几个小时的实验,我看到了最奇怪的行为!我想我的.htaccess文件可能只是被忽略了,所以我用胡言乱语填充了它。这产生了预期的内部服务器错误。然后我在.htaccess文件中只尝试了这两行。。。

RewriteEngine On
RewriteRule ^/(.*)$ /${lc:$1}

尝试访问test/phpinfO.php失败。然后我删除了.htaccess文件,并将这两行直接放入我的"/etc/apache2/sites-available/default"文件中,然后重新启动Apache。出于某种莫名其妙的原因,我想要的行为现在奏效了!我无法可能理解如何操作,因为我唯一的规则不是在URL上附加".php"!

这听起来可能很奇怪,但感觉我的改变正在以某种延迟的方式生效。我尝试了其他一些测试,但这些测试没有立即奏效,但后来似乎在不应该奏效的时候奏效了。我一直在测试,并期望我当前的设置在不更改任何内容的情况下中断。不管是什么情况,我都非常困惑。

希望有人能在我把我的大脑挖出来用大锤砸碎之前对此有所了解。

我终于弄明白了这一点。好吧,至少是其中的一部分。事实证明,"MultiViews"选项负责解析没有".php"扩展名的文件。再加上我的"/etc/apache2/sites-available/default"文件中的这两行,我就得到了我想要的行为:

RewriteEngine On
RewriteRule ^/(.*)$ /${lc:$1}

不幸的是,我无法确定为什么当我的.htaccess文件具有上述规则时会被忽略,而当它有胡言乱语时不会被忽略。

编辑:好的,我弄清楚了.htaccess文件不工作的原因。它正在被阅读,但第二条规则不匹配。根据Apache文档,原因如下:

删除的前缀总是以斜杠结尾,这意味着匹配发生在从不包含前导斜杠的字符串上。因此带有^/的模式在每个目录上下文中从不匹配。

因此,我更改了.htaccess文件,使其具有。。。

RewriteEngine On
RewriteRule ^(.*)$ ${lc:$1}

它终于起作用了!

CheckSpelling on

匹配文件和目录。有关详细信息,请参阅文档。

复制自=具有mod_rewrite 的大小写不敏感URL