Apache: как переписать URL-адрес без расширения файла и игнорировать регистр?

Я запускаю Ubuntu 12.04 с Apache 2.2.22 и PHP 5.3.10. Я бы хотел, чтобы пользователи могли запрашивать страницы на моем сайте, не набирая расширение «.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 ^([az]+)/([az\-]+)$ /${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 

Любые идеи, что я делаю неправильно здесь?

EDIT: После эксперимента в течение нескольких часов я вижу самое причудливое поведение! Я подумал, что мой файл .htaccess просто игнорируется, поэтому я наполнил его тарабарщиной. Это вызвало ошибку внутреннего сервера, как ожидалось. Затем я попробовал только эти две строки в моем файле .htaccess …

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

… и попытался получить доступ к тесту / phpinfO.php безуспешно. Затем я удалил файл .htaccess и поместил эти две строки непосредственно в файл «/ etc / apache2 / sites-available / default» и перезапустил Apache. По какой-то необъяснимой причине поведение, которое я хотел, теперь работает! Я не могу понять, как, поскольку мое единственное правило не добавляет «.php» к URL!

Это может показаться странным, но похоже, что мои изменения вступают в силу некоторым отсроченным способом. Я пробовал некоторые другие тесты, которые не срабатывали сразу, но это, похоже, срабатывало позже, когда им этого не было. Я продолжаю тестировать и ожидаю, что моя текущая установка сломается, ничего не изменив. В любом случае, я абсолютно сбит с толку.

Надеюсь, кто-то может пролить свет на это, прежде чем я разорву свой мозг и разгромию его кувалдой.

Я, наконец, понял это. Ну, по крайней мере, часть этого. Оказывается, опция «MultiViews» отвечала за разрешение файлов без расширения «.php». Это в сочетании с этими двумя строками в моем файле «/ etc / apache2 / sites-available / default» дает мне поведение, которое я желаю:

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

К сожалению, я не смог определить, почему мой .htaccess-файл игнорируется, когда он имеет вышеуказанные правила, но не игнорируется, когда он имеет тарабарщину.

EDIT: Хорошо, я понял, почему файл .htaccess не работает. Это читалось, но второе правило не соответствовало. Вот почему, согласно документации Apache :

Удаленный префикс всегда заканчивается косой чертой, что означает, что сопоставление происходит с строкой, которая никогда не имеет косой черты. Следовательно, шаблон с ^ / никогда не совпадает в контексте контекста.

В результате я изменил файл .htaccess, чтобы …

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

… и это, наконец, работает!

 CheckSpelling on 

Соответствует файлам и каталогам. Подробнее см. В документации .

Скопировано из = Нечувствительные к регистру URL-адреса с mod_rewrite