Niedziałający mod_rewrite – rozwiązanie

Ostatnio pisząc nowy skrypt strony (tego obecnego nie można już w żaden sposób uratować bo to jeden wielki śmietnik, praktycznie uczyłem się dopiero PHP pisząc go) natrafiłem na dość poważny problem. Obecna strona używa z powodzeniem mod_rewrite, więc aby nie cofać jej w rozwoju użycie tego modułu było jednym z podstawowych celów kolejnej wersji skryptu. Niestety już po napisaniu kilku regułek okazało się, że niektóre z nich działają a niektóre nie. Początkowo próbowałem radzić sobie w możliwie najprostszy sposób używając REQEST_URI zamiast korzystać z GETa. Po napisaniu kilku podstron kontynuowanie takiego obejścia okazało się niemożliwe. Zauważyłem, że problemy sprawiają te reguły, w których jako wzorzec zawarty jest ciąg występujący również w pliku na serwerze np.

RewriteRule ^projekty/([0-9]+)$ projekty.php?strona=$1

To już dało mi do myślenia i zacząłem kombinować co jest źródłem problemu. Jak przypuszczałem zmiana projekty we wzorze na dowolny inny ciąg powodowała, że problem znikał. Trudno jednak, aby użytkownik chcąc obejrzeć moje projekty wchodził na podstronę nazywającą się blablabla lub jakkolwiek inaczej. Zmiana nazwy pliku projekty.php też nie wchodziła w grę, bo utrudniałaby tym razem moje życie. W takiej sytuacji zacząłem szukać sposobu na podejrzenie co robi serwer oraz jakie dane dostaje. Możliwe to było do osiągnięcia jedynie dzięki logom. Jako, że serwer stoi na localhoście nie stanowiło to problemu. Do konfiguracji Apache’a dopisałem:

RewriteLog [sciezka do serwera]/logs/rewrite.log
RewriteLogLevel 5

Zresetowałem i otworzyłem log. Po bardzo szybkiej analizie (większości wpisów nawet nie trzeba rozumieć, wystarczą ścieżki) zauważyłem, że moduł rewrite zamiast projekty/1 dostaje projekty.php/1. Niestety nie wiedząc jaki jest powód takiego zachowania serwera odpuściłem sobie przez co straciłem dwa dni nie pisząc ani jednej linii nowego kodu.

Kiedyś jednak musiałem do niego wrócić. Wróciłem więc dzisiaj i zacząłem analizować konfigurację Apache’a. W pliku httpd.conf nie znalazłem nic co mogłoby powodować ten błąd. Jako, że wykorzystuję WAMP’a jako platformę testową (i nie tylko, bo screeny użyte we wpisie Kilka ciekawostek z bazy whois (i nie tylko) także pochodzą z mojego localhosta tylko z zupełnie innego skryptu, którego nie mam zamiaru teraz omawiać) miałem utworzony alias do skryptu (tego od bazy whois) a strona znajdowała się dodatkowo w podfolderze (co wcześniej uważałem za przyczynę błędu, okazało się jednak, że leży ona gdzie indziej). Zajrzałem więc do konfiguracji aliasu. Wygląda ona mniej więcej tak:

<Directory "x:/system/htdocs/">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
        Order allow,deny
    Allow from all

Nie wklejam całości, żeby nie zaśmiecać wpisu. Od razu rzuciły mi się w oczy dwa elementy: MultiViews oraz AllowOverride all. Alias został wygenerowany przez WAMPa a dodatkową konfigurację pobrałem z Internetu. Trudno powiedzieć skąd wzięła się akurat ta część. W każdym razie zacząłem szukać informacji o MultiViews dzięki czemu trafiłem tutaj. Pomijając problemy jakie mógłbym mieć z Googlebotem gdyby taka konfiguracja była na serwerze dostępnym z Internetu autor wyjaśnia co robi ta dyrektywa:

Multiviews allow substitutions of file extensions, so you can call an URL like www.somehost.org/mypage.php using www.somehost.org/mypage.

Po przeczytaniu tego zdania od razu jasne stało się, że właśnie znalazłem źródło swojego problemu. Oczywiście dodając Options -MultiViews na początek pliku .htacces regułki zaczęły działać dokładnie tak jak powinny. Wniosek z tego jest taki, że gdy nie wiesz dlaczego coś nie działa zawsze czytaj logi!

This entry was posted in Tutorials and tagged , , , , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback.

Leave a Reply

Your email address will not be published. Required fields are marked *

Your email address will never be published.