![]() |
![]() |
![]()
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ę:
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:
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 |
|
|
![]() |
![]()
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 |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 279 Pomógł: 60 Dołączył: 25.02.2012 Ostrzeżenie: (0%) ![]() ![]() |
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. |
|
|
![]() ![]() |
![]() |
Aktualny czas: 14.10.2025 - 11:46 |