Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Routing
szaleq
post
Post #1





Grupa: Zarejestrowani
Postów: 18
Pomógł: 0
Dołączył: 22.08.2009

Ostrzeżenie: (0%)
-----


Witam

Mam wątpliwości odnośnie logiki działania routingu w aplikacji implementującej MVC.
Na wstępie słowo odnośnie mojej implementacji:
Aplikacja składa się z modułów, każdy moduł ma swoje kontrolery widoki i modele. Tak więc router musi zwrócić prócz kontrolera i akcji nazwę modułu (oraz opcjonalnie parametry).

Mój dylemat opiszę na podstawie tras dynamicznych (router obsługuje również trasy statyczne oraz regex). Trasy definiuję podając "ścieżkę" oraz tablicę wartości "domyślnych"
i tak mam np trasę:
  1. $router->setRoute(':module/:controller', array(
  2. 'action' => 'index'
  3. ));

Dla ścieżki np. 'blog/posts' router, stwierdziwszy, że podana ścieżka pasuje do danej trasy, zwróci tablicę: ('module' => 'blog', 'controller' => 'posts', 'action' => 'index').

Jednak gdy zdefiniuję kolejną trasę następująco:
  1. $router->setRoute(':controller/:action', array(
  2. 'module' => ':controller'
  3. ));

pojawia się problem. Gdyby router przypasował daną trasę np do ścieżki 'articles/all', zwróciłby tablicę: ('module' => 'articles', 'controller' => 'articles', 'action' => 'all').

Jednak podana ścieżka ('articles/all') pasuje do obu powyższych tras. Obecnie działający router zwróci więc tablicę na podstawie pierwszej ścieżki: ('module' => 'articles', 'controller' => 'all', 'action' => 'index'). Oczywiście nie istnieje taki kontroller jak 'all' w module 'articles' więc pojawi się błąd 404.

I tu mój dylemat: czy router powinien zwracać tablice przypasowań dla wszystkich pasujących tras? wtedy dispatcher stwierdziwszy, że nie ma kontrolera o nazwie 'all' sięgnąłby po następny wynik i trafił na właściwy kontroler.
Teoretycznie sprawa prosta w działaniu oraz w implementacji, ale czy przy większej ilości tras pasujących do danej ścieżki nie odbiłoby się to na wydajności? Czy ktoś spotkał się z takim routingiem lub może robił coś podobnego...?

Piszcie, co o tym myślicie.

Pozdrawiam
szaleq
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
szaleq
post
Post #2





Grupa: Zarejestrowani
Postów: 18
Pomógł: 0
Dołączył: 22.08.2009

Ostrzeżenie: (0%)
-----


@irmidjusz
Oczywiście, nie sposób nie przyznać Ci racji. Napisałem jednak, że "Przeglądałem wiele istniejących rozwiązań". Często zagłębiam się w kod licznych frameworków, przeglądam również np skrypty na phpclasses.org i wiele się w ten sposób uczę. Nie miewam problemów ze zrozumieniem czyjegoś kodu. Jednak po przestudiowaniu stu przykładów zawsze robię sto pierwszy po swojemu. I uważam, że słusznie.

Wracając do sedna tematu, akurat router Zenda przejżałem dość powierzchownie. Analizowałem jednak setki przykładów opisywanych na blogach, czy forach, przejżałem Symfony i Kohanę. No i np w kohanie wydaje mi się (może coś przeoczyłem?), że routing kończy się w momencie znalezienia pierwszej pasującej trasy. Moje pytanie dotyczy tylko i wyłącznie faktu, że aby szukać kolejnego dopasowania należy sprawdzić, czy pierwsze z brzegu dopasowanie jest prawdziwe co wiąże się z ładowaniem pliku klasu kontrolera. Sprawdzanie, czy plik istnieje, to dodatkowy czas i obciążenie dla serwera. Przy założeniu że mam kilka tras pasujących do danej ścieżki a w danym zapytaniu pasuje ostatnia trasa, muszę najpierw próbować załadować kilka plików nim trafię na ten właściwi. Czy to opłacalne? czy tak się robi? tylko o to pytam.
Jeśli sugerujesz, że tak właśnie działa routing w Zend Framework, dzięki za wskazówkę. Zagłębię się bardziej w jego kod.

Pozdrawiam
szaleq
Go to the top of the page
+Quote Post
irmidjusz
post
Post #3





Grupa: Zarejestrowani
Postów: 279
Pomógł: 60
Dołączył: 25.02.2012

Ostrzeżenie: (0%)
-----


Cytat(szaleq @ 1.09.2012, 23:14:08 ) *
Jednak po przestudiowaniu stu przykładów zawsze robię sto pierwszy po swojemu. I uważam, że słusznie.

Też tak uważam.

A wracając do routingu, zasadniczo masz dwie podstawowe możliwości:

1) następuje tylko i wyłącznie dopasowywanie do istniejącego wzorca i pierwszy znaleziony jest uznawany za obowiązujący, więc jeśli nie istnieje spodziewany moduł/kontroler/akcja wynikający ze znalezionego wzorca, to jest błąd i koniec

W tym przypadku wszystko działa ok o ile wzorce dopasowań routingu są poprawnie określone - czyli m.in. nie może być niejednoznaczności w określaniu, jaką akcję wywołać, bo wykona się zawsze tylko pierwszy znaleziony. To rozwiązanie działa generalnie najlepiej, najprościej i najszybciej. W przedstawionym przez Ciebie zagadnieniu, jak sam zauważyłeś, ten sam wzorzec (<word1>/<word2>) chciałbyś móc rozwiązać na dwa wykluczające się sposoby (moduł/kontroler i kontroler/akcja). Z tego punktu widzenia, jest to po prostu błąd określania wzorców.

Możesz użyć też innego podejścia:

2) po znalezieniu wzorca, sprawdzane jest, czy aby odpowiedni moduł/kontroler/akcja istnieje, jak tak, jest wykonywana, jak nie, szukamy dalej...

I tak też można i będzie ok. Koszt sprawdzania jest różny - pytanie, czy w ogóle istotny. Generalnie można powiedzieć, że jeśli akcje są zaimplementowane jako metody kontrolerów, to sprawdzenie czy istnieje akcja w klasie kontrolera, który jest plikiem w folderze modułu, jest najbardziej kosztowne, więc lepiej sprawdzić jedynie, czy istnieje moduł <word1> a w nim kontroler <word2> (i wywołać akcję domyślną), a jak nie, to czy istnieje kontroler <word1> i wywołać w nim akcję <word2> (może być w odwrotnej kolejności). I są frameworki, które tak robią i żyją (IMG:style_emoticons/default/smile.gif) Więc nie jest to problem.
Z głowy spraw wydajności nie określisz. To tylko testy realnie działającego kodu są w stanie poprawnie pokazać. A akurat sprawdzenie istnienia jednego czy dwóch plików więcej jednorazowo w czasie obsługi requesta na pewno nie będzie głównym problemem wydajności (IMG:style_emoticons/default/tongue.gif) Nie mówiąc o tym, że możesz sobie np. napisać mechanizm, który na serwerze produkcyjnym skanuje wszystkie moduły, kontrolery i akcje i keszuje je do tablicy używanej przez routing. W tym podejściu, niejednoznaczne wzorce dopasowań routingu są akceptowalne a problemu z wydajnością może w ogóle nie być. Wszystko wedle życzenia, Twój projekt i jak zrobisz, tak będzie (IMG:style_emoticons/default/smile.gif) A czy dobrze, czy źle, to pojęcie względne i zależy, wg. jakich założeń i miar oceniasz.


Z tym Zendem chodziło mi o to, że tam też jest <moduł/kontroler> i <kontroler/akcja>. Jest to rozwiązane tak (standardowo):
- jak podajesz tylko /<word1> to jest traktowane jako akcja w domyślnym kontrolerze w domyślnym module,
- <word1>/<word2> to jest uznawane za kontroler/akcja w domyślnym module,
- jak podasz <word1>/<word2>/<word3> to jest mapowane na moduł/kontroler/akcja (gdy masz moduły)

W ten sposób wszystkie trzy się łatwo od siebie odróżnia. Ładne w teorii, gdy nie ma parametrów. Zabawa się zaczyna, gdy podajesz parametry, hihi. No i tu będziesz miał zabawę z prześledzeniem rozwiązania ZF (IMG:style_emoticons/default/wink.gif)
I zobacz jak jest w Yii, jak tam jest to dziwnie rozwiązane, i też działa i tyle ludzi go używa i jest ok.

Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 14.10.2025 - 11:46