snaers
24.03.2011, 22:29:42
Witam, postanowiłem trochę pobawić się w PHP obiektowo, przyszedł czas na MVC i o ile z modelem i widokiem raczej problemów nie mam to nie wiem jak poprawnie zrobić kontroler.
Mam stronę z:
- show.php
- edit.php
- add.php
- admin.php
Normalnie to na początku wyświetlałem index.php, no i potem linkami, ale to to nie jest kontroler, więc jak to rozegrać?
Na stronie index.php mam wywołać klasę kontrolera? A jak potem w tym pliku kontrolera to zrobić?
Przejrzałem kilka frameworkow, ale to mi jeszcze bardziej namieszało, więc prosiłbym o takie najprostsze naprowadzenie jakby to miało wyglądać.
Pozdrawiam!
PlayKiller
24.03.2011, 22:35:44
Router -> Controler (korzysta z Model) -> View
snaers
24.03.2011, 22:39:27
Racja, źle to pytanie zadałem. Jak zrobić ten router w najprostszy sposób? Wiem, że to ma być coś w stylu, że jak się wybierze np EDIT to przechodzę do klasy kontrolera i tam pobieram mu dane i otwieram plik edit.php, tylko jak to zrobić?
Pozdrawiam!
Fifi209
24.03.2011, 22:43:23
Cytat(snaers @ 24.03.2011, 22:39:27 )

przechodzę do klasy kontrolera i tam pobieram mu dane
Router odpala odpowiedni kontroler, który w zależności od akcji ma odpalić model, z modelu widok pobiera dane (bezpośrednio, bez komunikacji przez kontroler)
snaers
24.03.2011, 22:46:48
Ok, ok, ale wciąż nie bardzo wiem jakbym miał taki router zaimplementować. Jakby to w ogóle miało wyglądać?
thek
24.03.2011, 23:01:59
Router pobiera URL i parsuje go. Na podstawie tego co wyłapie uruchamia odpowiedni kontroler i przekazuje mu ewentualne parametry.
snaers
24.03.2011, 23:06:45
Czyli mam do tego użyć $_SERVER['REQUEST_URI']; ?
No dobrze, ale co dalej? W index.php mam linka do edit.php no i jak go kliknę to przecież przerzuci mnie od razu do tej strony edit.php, więc jak zrobić, żeby to w index.php przechwycić?
everth
24.03.2011, 23:07:52
Symfony w diagramach UML. Poprzeglądaj sobie jak to tam jest zbudowane, z jakich klas korzysta, w jaki sposób. Oczywiście i tak nie zaimplementujesz tego w taki sposób ale powinno ci to dać jakąś orientację jak zaprojektować te klasy.
Fifi209
24.03.2011, 23:07:59
Odpowiedni rewrite
RewriteRule .* index.php?costam=$0 [L]
Czyli przekierowanie wszystkiego na index
snaers
24.03.2011, 23:22:01
Symfony trochę oglądałem od strony kodu, ale to zdecydowanie za dużo jak dla mnie.
Fifi a jak mam zrobić takie przekierowanie jeśli mam na tym samym poziomie pliki index.php, edit.php itd? Nie wywołuję tego przez index.php?... Chyba, że tak trzeba?
Crozin
24.03.2011, 23:48:18
@PlayKiller, @fifi209, @thek: A co ma router do odpalania kontrolerów? Router przetwarza parametry żądania (w przypadku PHP będzie to albo żądanie HTTP albo komenda z CLI) i zwraca je w jakiejś zjadliwej formie. Od odpalania kontrolerów mamy jakiegoś dispatchera, który to routera jedynie wykorzystuje.
@snaers: Bardzo typowy przebieg zdarzeń:
Kod
[Front|Page] Controller -> Request -> Dispatcher -> Controler -> View -> Response
|| /\ \ /
|| || \ /
\/ || \ /
Router Model
snaers
25.03.2011, 00:13:18
No dzięki, ale dalej nie wiem jak się do tego zabrać pod względem kodu.
thek
25.03.2011, 01:10:48
Zastosowalem za duży skrót myślowy. Postaram to nieco łopatologiczniej ( choć także nieco po łebkach ) wyjaśnić...
Dostajesz żądanie do aplikacji, zazwyczaj wspomniane żądanie http, w najróżniejszej postaci. Jest ono kierowane do front kontrolera, który decyduje co z nim zrobić. Jeśli dostaje je już w zjadliwej formie, kieruje wprost do dispatchera. Przykładem takiego czegoś byłoby żądanie z jawnym wywołaniem pliku i jego parametrami get, a więc index.php?action=cos¶metr=param
Jeśli forma nie jest zjadliwa, czyli przykładowo index.php?/cos/param to wszystko, co przyszło musi zostać "przetłumaczone" na formę zrozumiałą dla dispatchera. W tym miejscu wskakuje router. On tłumaczy dla dispatchera, który na podstawie przetworzonego żądania wie co wywołać i z jakimi parametrami. To on przechowuje reguły, dzięki którym wie, że taki a taki ciąg odpowiada w rzeczywistości za odwołanie do określonego kontrolera z danymi parametrami. Tę wiedzę przekazuje do dispatchera, który to ów kontroler już wywołuje.
Co do kodu to router najczęściej jest kawałkiem, który obrabia otrzymane żądanie (najczęściej jest to URL żądania lub parametry z linii komend) do postaci obiektu lub tablicy z danymi o kontrolerze i jego parametrach. Często jest to realizowane poprzez wyrażenia regularne lub podobne im funkcjonalnie mechanizmy.
Podam przykład...
www.domena.pl/obiekt/nazwa/id/
Router wie że ma domyślnie dzielić to co za nazwą domeny po / i po kolei są to kontroler, metoda, parametry i stąd otrzyma tablicę
( kontroler => obiekt, metoda => nazwa, parametry => id )
i w takiej formie przekazuje ją dispatcherowi. Może mieć jednak inne reguły. Przykładowo istnieje w nim reguła, że dla takiej konstrukcji, jest niejawnie wywoływana metoda show. Czyli tak naprawdę powinno tam być www.domena.pl/obiekt/show/nazwa/id/ i w formie tablicy
( controler => obiekt, metoda => show, parametry => ( nazwa, id) )
rzuca ją do dispatchera. W ten sposób działa routing. Dostaje on żądanie i porównuje z wzorcami. Jesli dopasuje, obrabia i zwraca dispatcherowi. Jeśli nie, to stosuje regułę domyślną i też zwraca dispatcherowi. Routera nie interesuje nic innego niż owa konwersja. To czy kontroler, metoda lub parametry istnieją - nie obchodzi go.
lukaskolista
25.03.2011, 08:52:30
Cytat(PlayKiller @ 24.03.2011, 22:35:44 )

Router -> Controler (korzysta z Model) -> View
Cytat
Widok jest odpowiedzialny za prezentację danych w obrębie graficznego interfejsu użytkownika. Może składać się z podwidoków zarządzających mniejszymi elementami składowymi. Widoki posiadają bezpośrednie referencje do modeli, z których pobierają dane, gdy otrzymują od kontrolera żądanie odświeżenia. Widoki mogą także modyfikować stan modelu, jeśli dana modyfikacja dotyczy sposobu prezentacji danych[5].
jak mozna przeczytac w MVC kontroler nie steruje modelem, PHPowe frameworki jedynie implementuja w czesci MVC (co wedlug mnie jest lepsze, niz prawdziwy MVC)
Tez uwazacie, ze implementacje MVC w PHPowych frameworkach w przypadku tego jezyka sa lepsze, niz pelna, 100% implementacja MVC? Osobiscie uzywam kohany+ORM i caly kod pisze w kontrolerze i jest mi z tym bardzo dobrze, model ma jedynie kilka przydatnych funkcji do obslugi danych, a widok jedynie wyswietla te dane w HTML. Widzialem juz aplikacje, w ktorych wiekszosc akcji wykonywana jest w modelu i dla mnie jest to balagan niedoogarniecia. Wole dluzszy, ale bardziej przejrzysty kod.
Prosze nie oceniac tego bo nie twierdze, ze jest to MVC i ze kazdemu musi to pasowac.
Tez uwazacie, ze implementacje MVC w PHPowych frameworkach w przypadku tego jezyka sa lepsze, niz pelna, 100% implementacja MVC? Osobiscie uzywam kohany+ORM i caly kod pisze w kontrolerze i jest mi z tym bardzo dobrze, model ma jedynie kilka przydatnych funkcji do obslugi danych, a widok jedynie wyswietla te dane w HTML. Widzialem juz aplikacje, w ktorych wiekszosc akcji wykonywana jest w modelu i dla mnie jest to balagan niedoogarniecia. Wole dluzszy, ale bardziej przejrzysty kod.
Prosze nie oceniac tego bo nie twierdze, ze jest to MVC i ze kazdemu musi to pasowac.
thek
25.03.2011, 09:22:58
Lukaskolista... Dobrze, że zastrzegłeś o tym MVC i że nie twierdzisz tego bo by Cię tu zagryźli pewnie ortodoksi

K2 implementuje MVP, a K3 HMVC(P). Niestety ale pełna implementacja MVC w środowisku web nie jest możliwa z powodu samej architektury. protokół bezstanowy, kounikacja jako żądanie. To wszystko uniemożliwia prawidłową implementację tego wzorca w sieci web.
Co do kodu to zależy jak leży. Ja w modelu obrabiam dane, bo to jego działka. Kontroler ma sterować a widok wyświetlać. Jeśli dla zmiany widoku konieczne byłoby znaczne kombinowanie z przebudową kontrolera - podziękuję. Przykład? Masz wyświetlić strone jako html... Fajnie. Wysyłasz żądanie do modelu by Ci to dał,potem ustawiasz widok, obrabiasz w kontrolerze dane modelu i... nadchodzi konieczność generowania strony jako pdf. Tworzysz kolejny kontroler bo obecny sie do tego nie nadaje z racji przejęcia części zadań modelu? Źle. Musisz maksymalnie odseparować te działania. Model ma już zwrócić uniwersalne, przetworzone dane a kontroler ma je tylko do widoku pchnąć. Kontroler powinien jedynie albo zmienić widok z html na pdf, albo sam widok powinien się połapać, że ma ustawić inny nagłówek i nieco inaczej dane potraktować. To jest właśnie prawidłowy schemat działania, a nie robienie wszystkiego w kontrolerze. Kohana na to pozwala, ale nie oznacza to automatycznie, że jest to prawidłowa implementacja wzorca. Zwyczajnie została tak napisana, że możesz wszystko zrobić kontrolerem, bez odwoływania się do modelu lub widoku. A to nie jest prawidłowe w żadnym wypadku.
snaers
25.03.2011, 10:37:00
A MVC w Symfony jest poprawne? Na tej podstawie można się uczyć tego modelu?
To może mi ktoś napisać jak się za to mam zabrać?
Mam te 3 pliki: index.php, admin.php i edit.php. edit.php musi być wywołane z parametrami, np edit.php?id=2 . admin.php po prostu przenosi do panelu admina.
index.php:
//...
<a href="/show?id=
<?php echo $post['id'] ?>">TEST </a>
//...
<a href="/admin.php">Panel admina</a>
I teraz wystarczy reguła:
Cytat
RewriteRule .* index.php?costam=$0 [L]
? Ale wciąż jak wejdę na admin.php to w adresie mam admin.php, a nie to...
Pozdrawiam!
thek
25.03.2011, 11:24:20
By nauczyć prawidłowo wzorcy czytaj dokumentację. Nie wiem jak z MVC w Symfony bo nie pracowałem z tym FW. Tu muszą inni odpowiedzieć.
Jeśli chodzi o to co napisałeś, to szczerze mówiąc średnio to rozumiem co robisz. Poza tym jeśli chcesz sobie wszystko dobrze sprawdzać, to weź odpal apache'a, ustaw zapis do logów i daj najwyższy poziom logowania (pamiętaj, że wtedy ładowanie stron zacznie trwać wieki

), a w logach zaczna Ci się też zapisywać przekierowania także htaccessa. Wtedy zobaczysz co gdzie jest kierowane. To Ci powinno powiedzieć dokładnie co robisz źle, lub co się
nie wykonuje, choć się tego byś spodziewał.
snaers
25.03.2011, 12:16:48
Ja też nie wiem jak to działa, bo to jest przykład, który dał Fifi we wcześniejszych postach, dlatego pytam, bo nigdy czegoś takiego nie robiłem.
Ok pogrzebałem trochę i znalazłem coś takiego:
http://piotrekk.jogger.pl/2010/01/04/prosty-router-w-php/Pomoże mi ktoś teraz to dostosować? Co mam zrobić w pliku htaccess i co mam zrobić w index.php?
thek
25.03.2011, 12:27:59
No przecież masz gotowy prosty router... Co więcej Ci trzeba? Napisać regułkę jedną w htaccess, która przekieruje cały ruch na front controller i którą już Ci tu podano? A potem napisać kod aplikacji w dispatcherze tak, by to co sparsował router do segmentów odpowiednio wywołać? Bez żartów... Masz niemal cały kod jak na tacy i teraz już po prostu prosisz o gotowca by Ci z tego zrobić. Ja Ci wytłumaczyłem łopatologicznie, Kod jaki dano robi to co opisałem, podano Ci jak przekierować ruch na front controller i teraz jedynie musisz w dispatcherze to wywołać... Po prostu lenistwo się szerzy...
snaers
25.03.2011, 12:44:54
Nie chciałem gotowca tylko naprowadzenie. Dalej po prostu nie wiem jakby to miało wyglądać. Dla was to może proste, ale dla mnie nie, więc chciałem uzyskać pomoc. Pisałem, że dopiero zaczynam z OOP i chciałem od razu pisać tak jak się powinno, więc póki co nie mam takiej wiedzy, żeby sobie taką klasę wykorzystać. Dla kogoś kto umie napisanie paru linijek kodu jakby to miało wyglądać to chyba nie problem, a po to też jest forum.
thek
25.03.2011, 13:41:27
Ale o to chodzi, że nie wiemy nic o Twoim kodzie. Nie wiemy jak wygląda struktura plików, jak to masz zamiar rozwiązać. jedyne co można napisać to tyle, że musisz załadować odpowiednie klasy, które dostał dispatcher z routera i wykonać ich metody z konkretnymi parametrami, które także router dispatcherowi przekazał. Musisz mieć więc jakiś system ładowania klas, tworzenia obiektów i wywoływania ich metod z parametrami lub bez. A to jak to już jest kodem implementowane, to już zależy od struktury Twojej aplikacji. Tak więc nie chodzi o to, że nie chcemy Ci pomóc, ale zwyczajnie bez pewnych założeń odgórnych nie można tego zrobić. Bo jak mamy choćby ładować klasę i tworzyć jej obiekt, skoro kompletnie nie znamy tego jak przechowujesz definicje klas i gdzie oraz w jakiej formie.
snaers
25.03.2011, 14:16:15
No tak, masz rację. Nie podałem nic, bo nic nie mam. Chce się tego zacząć uczyć, więc chciałem to po kolei robić, a nie naładować kodu, a potem się męczyć z przerabianiem. Napisałem tylko jakie mam pliki. No więc tak:
Struktura plików:
- htdocs
-- index.php
-- /templates/
--- list.php // wyświetla z bazy
--- edit.php // edytuje po id, czyli np edit.php?id=2
--- show.php // show.php?id=2
--- admin.php // to jeszcze nie wiem jak zrobię, ale podaje jako przykład, żebym wiedział jak się do tego odwołać w routingu
-- /model/
--- model.php //laczenie z baza itp
-- /controller/
--- class_router.php
list.php
foreach itd...
<a href="/templates/show.php?id=
<?php echo $post['id'] ?>">POKAZ </a>
class_router.php
index.phprequire_once '/controller/class_router.php';
require_once '/templates/class_router.php';
//no i tutaj mam po prostu:
include "list.php";
<a href="/templates/admin.php">Panel admina</a>
No i co dalej? Wiem, że muszę w index.php zrobić new class_router; i na tym moje pomysły się kończą, bo nie wiem jak to dalej zrobić.
Dostałem od was tą regułę:
Cytat
RewriteRule .* index.php?costam=$0 [L]
Ale niewiele mi to mówi. To oznacza, że wszystko co wywołam to jest kierowane na index.php?costam?
Czyli może powinienem zrobić coś w stylu:
Cytat
RewriteRule ^edit$ index.php?edit.php=$0 [L]
RewriteRule ^show$ index.php?show.php=$0 [L]
i wtedy jak się mam w takim razie odwoływać do tych plików?
Zakładając, że to jest dobrze, a pewnie nie jest to jak jaką teraz zrobić regułę dla admin.php, żeby też był brany pod routing?
No i najważniejsze - jak w ogóle zacząć z tym dispatcherem?
Pozdrawiam i proszę o pomoc
Crozin
25.03.2011, 14:59:35
Cytat
- Chcę zbudować samochód, jak to zrobić?
- Zobacz sobie jak działają obecne samochody, podpatrz istniejące rozwiązania.
- Nie, nie... Naładuję sobie tylko masę żelastwa i będę męczył się w przerobieniem tego.
...Ej to jak zrobić hamulec ręczny?
Nikt Ci tu nie będzie pisał książek o tym jak dobrze zaplanować architekturę aplikacji internetowej. I nie, słowo "książka" obok "dobrze" to nie jest żadne wyolbrzymienie.
snaers
25.03.2011, 15:07:28
Ale mi nie o to chodzi! Od początku tego tematu chodzi mi o to jak zrobić router w najprostszy sposób, leci druga strona, a poza teorią (potrzebną i dzięki za nią) nie dostałem jakichś przykładów na podstawie których mógłbym zacząć.
thek
25.03.2011, 16:42:28
Ale jak nie? Opisaliśmy Ci jak działa router wraz z prostym przykładem, co kod znaleziony przez Ciebie później potwierdził w 100%, ale to co Ty chcesz wykracza już poza ramy "Co to jest router i jak go zrobić", bo to już masz. To co teraz wołasz o pomoc to już problem stworzenia struktury aplikacji, autoloadera klas, projektu i implementacji front controllera oraz dispatchera. To się nieco wiąże z routerem, ale tylko powierzchownie. Że się posłużę przerobionym przykładem Crozina:
Chciałeś od nas wiedzy o kołach i Ci ją przekazaliśmy, ale nadal twierdzisz, że nie, choć jako mechanicy uważamy, że nie mówisz już o kołach, ale chcesz by Ci wytłumaczyć zasadę działania CAŁEGO podwozia.
snaers
25.03.2011, 17:19:37
Napisałeś, że nie wiecie jak u mnie wygląda cała struktura i dopiero wtedy mi możecie pomóc, więc napisałem o tym jak to u mnie wygląda, a teraz się okazuje, że jednak nie pomożecie. Pewnie chodzi o kilka linijek kodu, a zamiast tego wolicie mi pisać coś o samochodach.
Crozin
25.03.2011, 17:34:30
Nie, nie chodzi o kilka linijek kodu. Ale oczywiście za trudno poszukać pod frazą "php router", co nie? Pierwszy lepszy wynik:
https://github.com/symfony/symfony/tree/mas...mponent/Routing
thek
26.03.2011, 02:04:49
O przepraszam... Na PW Ci napisałem więcej niż tylko o strukturze. Cri rzucił adres do repozytorium Symfony dotyczące jedynie samego routera. Widzisz różnicę między kodem jaki pokazałeś jako prosty i tym spod linka. A czemu taka kolosalna różnica? Bo oba tyczą zupełnie różnych aplikacji. I co z tego, że mają ten sam cel i w sumie robią to samo? Oba dotyczą zupełnie innych aplikacji i muszą być zaimplementowane w sposób zgodny z danym projektem. A to zależy od wielu czynników już. Jednym z nich jest to co podałeś ale skąd mamy wiedzieć jak przykładowo dispatcher ładuje klasy czy jak wygladają Twoje klasy kontrolerów, by dispatcher mógł je wywołać w sposób prawidłowy. Takich pytań jest więcej. I sam zauważ, że ja juz mówie w tym momencie nie o routerze. Router ma proste zadanie. Dostaje ciąg jakiś na wejście i przetwarza go na obiekt danych zrozumiały dla dispatchera. A to już podany przez Ciebie kod realizuje, tylko musisz dostosować teraz dispatcher do tego by odpowiednio resztę aplikacji "rozruszał". Widzisz, że to już wykroczyło poza ramy routera czy jeszcze nie? A to jak dispatcher ma działać, jest zależne właśnie od wspomnianych przeze mnie elementów, pośrod których jest ta przytaczana struktura plików i katalogów.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.