Delta Plaground » Notes 2

Niceurle

szczegóły
  • z dnia: 2005-11-11 12:42:36
  • kategoria: Porady
  • permalink: Niceurle
powiązane

Rzecz o tym, co zrobić, żeby nasze adresy URL wyglądały dobrze.

Zanim padnie pytanie "a po co?" wytłumaczę o co mi chodzi. Internet w procesie swojego rozwoju zapomniał w pewnym momencie o takich pojęciach jak dostępność, jak funkcjonalnośc czy użyteczność. Wiele jego elementów zostało wykształcone nie kładąc nacisku na późniejsze zastosowania (szersze niż pierwotne) oraz na jego poprawność semantyczną i wiele innych. Mówiąc prosto: wiele rzeczy po prostu jest i nikt się nie zastanawia nad tym, czy nie mogłoby być lepiej. Najlepiej obrazującym to przykładem jest tworzenie adresów stron WWW, na którym to opiera się cały ten tekst.

Trzeba jeszcze wspomnieć, że jeśli można do serwisu internetowego dodać użyteczności czy funkcjonalności kosztem włożenia pewnej pracy w to - to należy bezwzględnie tą pracę wykonać. Po co komu serwis, który "tylko działa"? Mądrze włożony wysiłek zwróci się z pewnością.

A więc nieszczęsne adresy stron. Przedstawię na początku wzór wg jakiego są one konstruowane (przy czym w3c opracowało dokładną dokumentację:

http://host.domena.tld/ścieżka/plik.roz?zmienne#fragment

Pierwsze przyzwyczajenie jest takie, że host zawsze równy jest trzem znakom: www. Istnieje nawet cała kampania na rzecz porzucenia tego przyzwyczajenia: No-WWW.org. Domena jest wszak domeną i nie ma różnycy, czy wpiszemy w tamtym miejscu www, blog czy ziuteczek, nadal będzie ona działać w ten sam sposób. Jednak nie o tym będę mówił tym razem.

Zastanówmy się, co niosą za sobą pozostałe człony adresu

ścieżka
buduje drzewo struktury strony, sortuje dane w pewnej hierarchii. W większości ścieżka jest poprawna pod warunkiem, że istnieje: bo wiele serwisów, stron domowych blogów itp. korzysta jedynie z głównej ścieżki, nie pokazują separując informacji w adresie.
plik.roz - nazwa pliku
Im bliżej prawej strony, tym gorsza semantyka. Czy komukolwiek z internautów potrzebna jest informacja, że zapisaliśmy naszą stronę w pliku o rozszerzeniu np. php? albo html? Nie sądzę. Sama nazwa pliku owszem, może być przydatna, o ile sensowna: przykładowo 'index2.php' jest moim zdaniem zupełną głupotą.
zmienne - ciąg w postaci: zmienna=wartosc&zm2=cos_innego
No i meritum. Dobrze o tym mówi pornel w artykule dobre linki, więc ja już nie będę po nim poprawiał.

Teraz trzy sposoby na osiągnięcie przyjaznych adresów (niceurl - z angl: miły adres).

Mój faworyt, najwygodniej stosowany w niebardzo rozbudowanych serwisach, łatwy do osiągnięcia to Multiviews. Dzięki oprogramowaniu serwerowemu apache możemy bezkarnie pomijać rozszerzenia plików w adresie. Do nazwy zostanie dopasowany najlepiej pasujący plik w procesie tzw. content negotiation (patrz: poprzedni link). O ile nie mamy w danym katalogu plików o takich samych nazwach (różniących się jedynie rozszerzeniem) to nie występują tu żadne problemy. Nazwa pliku jest teraz częścią ściezki - tworzy korzeń hierarchii, a zmienne przekazywane przez adres traktowane są jako kolejne gałęzie. Już tłumaczę. Adres postaci: /forum.php?temat=10&strona=2 zostanie w przekształcony do niceurla: /forum/10/2. Widać na pierwszy rzut oka skrócenie adresu i poprawienie czytelności. Oczywiście trudniej jest przetworzyć tak przekazane dane, ale nie jest to niemożliwe. Zajrzyjmy do zmiennej $_SERVER[PATH_INFO] (oczywiście nasz skrypt znajduje się w pliku forum.php). Znajdziemy tam wszystko czego potrzebujemy i rozdzielimy (explode) do konkretnych zmiennych:

list( $temat, $strona ) =
 explode( '/', ltrim( $_SERVER['PATH_INFO'], '/' ) );

Drugi sposób, używany raczej do pojedyńczych stron, mniej zautomatyzowany to mod_rewrite, na którego brak w home.pl narzekałem ostatnio. mod_rewrite jest modułem dołączanym do apache`a, który pozwala na podstawie określonych, bardzo rozbudowanych kryteriów, przepisać (rewrite) jeden adres na drugi. Jest to proces wewnętrzny oprogramowania serwerowego, więc niewidoczny dla użytkownika. Dla przykładu, skorzystajmy z identycznego schematu jak w multiviews (poprzednia metoda):

RewriteRule /forum/([0-9]+)/([0-9]*) 
forum.php?temat=$1&strona=$2
#oczywiście w jednej linijce powinno być

Działania mod_rewrite nie będę tłumaczył, bo to długa i poruszająca wiele pobocznych tematów sprawa. Podam jednak linki do opisu tego modułu oraz strony Jacka Danielsa i jego mod_rewrite cheat sheet (polecam). Dodam jeszcze, ze w naszym przykładzie odpowiednie dane ('10' i '2') zostały automatycznie wpisane do superglobalnej asocjacyjnej tablicy $_GET pod kluczami 'temat' i 'strona'.

Trzeci, najmniej profesjonalny sposób to ustawienie dyrektywy ErrorDocument, służącej do określania pliku, który zostanie używy w przypadku błędu 404 (jeśli rządany przez użytkownika plik nie zostanie odnaleziony, na przykład tak jak na delcie). Specjalnie napisany skrypt powinien przeanalizować dane zawarte w $_SERVER[REDIRECT_URI] (będzie się tam znajdować cała ścieżka, np: '/forum/10/2') i zależnie od nich wykonać odpowiednią akcję, na przykład dołączyć inny plik ze skryptem. Wady są dwie, jedna mniejsza, druga poważna. Po pierwsze połączenie zwraca błąd numer 404. Niektóre programy mogą potraktować takie połączenie jako błędne (no i słusznie) i nie ściągnąć danych strony. Dotyczy to też wyszukiwarek internetowych. Przed tym można się zabezpieczyć wstawiając odpowiednią linijkę do skryptu, która spowoduje "anulowanie" błędu 404:

 header( 'HTTP/1.1 200 Ok' );

Musimy oczywiście wysłać nagłówek (to robi funkcja header() w PHP) zanim wyślemy jakiekolwiek inne dane, co jest udokumentowane w podręczniku. Druga sprawa jest jednak jednak nie do obejścia (jesli chcemy zachować przyjazne adresy oraz nie możemy skorzystać z innych wyżej wymienionych sposobów). Mianowicie, jeśli zapytanie jest wykonywane metodą POST (przeważnie wysyłane formularze wymuszają taką sytuację), to tablica superglobalna $_POST będzie pusta, a wszelkie dane, które zwykle są w niej zapisywane, stracone.

Podsumowując: metod jest wiele, ich charakterystyka zróżnicowana. Każdy musi wybrać taką, jaka jest mu bardziej porzydatna, łatwiejsza w użytkowaniu itp. Ja starałem sie jedynie obiektywnie przedstawić sytuację. Jeśli o czymś zapomniałem, to chętnie usłyszę sprostowania w komentarzach.

Archiwum