Pseudo-inteligentny router w PHP

tech • 501 słów • 3 minuty czytania

Wiem, że powinienem w tym czasie zamiast bawić się w PHP rozwijać te kilka ważnych dla mnie projektów w C++, ale doszedłem do wniosku, że poświęcę jeszcze trochę czasu na uporządkowanie kilku spraw i projektów, aby potem zabrać się pełną parą za komunikator ;)

Notatka nie będzie dotyczyć zabaw z typowym routerem, mowa tu o komponencie/module frameworka odpowiedzialnego za obsługę żądań (requestów) i spraw związanych z generowaniem linków. Może nie jest to typowe, modelowe zadanie routera, tak czy owak w moim małym, skromnym frameworku spełnia takie funkcje ;)

Właśnie kończę implementację odpowiedzialną za parsowanie requesta i wyciąganie odpowiednich danych o kontrolerze, akcji i dodatkowych parametrach.

BTW. Wcale ten router nie jest taki inteligentny, jak może sugerować tytuł, to miało być tak trochę ironicznie :P

Jednym z głównych założeń routera było osiągniecie zbliżonego działania do tego z CodeIgnitera. A precyzyjnie mówiąc to możliwość “inteligentnego odpalania” kontrolerów z sub-folderów z nieco większą elastycznością niż rozwiązanie zastosowane w CI. Tam (chyba) tylko kontroler mógł być zagnieżdżony o 1 poziom w sub-folderze względem głównego folderu kontrolerów. Ja u siebie nie chcę się ograniczać do jednego poziomu - chcę mieć nieograniczoną możliwość zagnieżdżania katalogów w dół. Pliki oczywiście mają większy priorytet niż katalogi…

Może kilka przykładów, które rozjaśnią zasady działania mojej implementacji.

Przy okazji, z ostatniego członu requesta będzie wycinane .html, jeśli takowe się tam znajdzie.

Mam requesta:

http://domena.com/foo/bar/param.html

Jaka zostanie odpalona akcja, z którego kontrolera i z jakimi parametrami?

Zależy to od struktury i rozmieszczenia pliku kontrolera, rozważmy kilka przypadków:

  1. W głównym katalogu kontrolerów istnieje plik foo.php.
    Wywołana zostanie akcja bar z parametrami param kontrolera foo.

  2. W katalogu /foo/ istnieje plik bar.php z definicją kontrolera.
    W tym wypadku użyty zostanie kontroler bar znajdujący się w sub-folderze foo, a akcją będzie metoda param.

  3. Połączenie 1 i 2, czyli istnieją pliki i foldery według 1 i 2 przypadku.
    Oczywiście wynik będzie taki jak w przypadku 1, bo jak wspomniałem plik ma większy priorytet niż katalog.

  4. Istnieją katalogi według ścieżki /foo/bar/ ale bez żadnych odpowiednich plików.
    Router w tym przypadku ustawia domyślny kontroler (index) znajdujący się w folderze /foo/bar/ z akcją param.

W przypadku requesta:

http://domena.com/foo.html

Router, jeśli znajdzie plik kontrolera foo, to wywoła metodę domyślną (index) tego kontrolera. Jeśli nie znajdzie pliku, a będzie istniał katalog /foo/ to wywoła domyślną akcję domyślnego kontrolera z tego katalogu.

Ja bym chciał w takim przypadku, aby została wywołana domyślna akcja z parametrem foo domyślnego kontrolera.

Wpadłem więc na pomysł, aby dodać do kontrolera dodatkową właściwość. Zależnie od jej wartości, jeśli w danym kontrolerze nie zostanie znaleziona szukana akcja, to zostanie przyjęta domyślna akcja z parametrem. Oczywiście parametr ten byłby ustawiany w czasie projektowania danego kontrolera i miałby widoczność lokalną ;)

Pozostaje jeszcze kwestia filtrowania żądania pod katem “złych/niebezpiecznych” znaków ;)

Pewnie niektórym nie spodoba się takie podejście i rozwiązanie, ale w końcu to będzie mój framework, prosty framework bez dzielenia 4 funkcji na 40 klas i rozrzucania po 10 folderach!, z którego głównie pewnie tylko ja będę korzystał, więc powinien spełniać jak najbardziej moje potrzeby i ułatwiać mi pracę ;)

Komentarze (4)

kwiateusz
20070712-095301-kwiateusz

ja tam chetnie sobie go obejrze jak skonczysz :D

Turgon
20070712-110952-turgon

Ciekawe :) Mógłbym troszkę sobie podkraść pomysł ;)? Z tym zagnieżdżaniem :-), bo to naprawdę ciekawy pomysł :) Przydałby mi się np. do budowy ACP ;) ?

NuLL
20070712-190839-null

Widze kolega tez preferuje swoje : ) Podobnie jak ja : ) I zgadzam sie z ostatnim akapitem dotyczacym prostoty - nie znosze przerostu formy na trescia ; ) Pzdr

Michał Słaby
20070713-224633-michal-slaby

Ciekawe, dość podobną funkcjonalność w zbliżony sposób implementuję w moim frameworku, tyle że tam posługuję się formatem katalog/katalog/…/klasa/metoda, przy czym katalogi są opcjonalne, a ich zagłębienie nieograniczone. Po za tym wszystko działa na Ajaksie ;-)

Zerknij, jeśli jesteś zainteresowany: http://tigermouse.epsi.pl

Dodaj komentarz

/dozwolony markdown/

/nie zostanie opublikowany/