Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Budowa kontrolera
Forum PHP.pl > Forum > PHP > Pro > Archiwum Pro
Jarod
Mam już prawie ukończonego frameworka. Z większych rzeczy pozostał mi do napisania kontroler. Podpatrywałem ZF, przeglądałem rózne arty znalezione na google na ten temat. Ale nadal zastanawiam się jak powinien być zbudowany kontroler. Tzn wiem co chcę osiągnąć ale nie wiem jak to podzielić na Front Controller i na kontrolery. Ogólnie chciałbym mieć możliwość wybierania modułów i akcji danego modułu na podstawie np. takiego linka:

Kod
http://serwer/module=module1/action=action1/value=1/value2=2/.../...


Możecie coś doradzić?
NuLL
Zbudowales framework bez kontrolera - ROTFL biggrin.gif

A o adresowaniu - to masz wyszukiwarke i slowo ROUTER.
Jarod
Cytat(NuLL @ 22.02.2007, 18:40:16 ) *
Zbudowales framework bez kontrolera - ROTFL biggrin.gif


Co Cię tak bawi?
devnul
też nie rozumiem co w tym śmiesznego - framework raczej nie ma w definicji posiadania kontrolera - to tylko zestaw narzędzi do budowania aplikacji - nigdzie nie jest powiedziane że kontroler musi być - bo to zależne jest od zastosowanego wzorca projektowego. To tak OT - a co do tematu to chyba na wortalu był jakis artykuł na ten temat.
LBO
Kontroler to serce frameworka - można przypuszczać, że to co nazywasz frameworkiem, to kilka klas, mocniej lub luźniej ze sobą związanych, ale nie ułatwiających pisania pełnej aplikacji.
Widzisz już gdzie jest pies pogrzebany?
Jarod
Cytat(LBO @ 22.02.2007, 19:36:42 ) *
Kontroler to serce frameworka - można przypuszczać, że to co nazywasz frameworkiem, to kilka klas, mocniej lub luźniej ze sobą związanych, ale nie ułatwiających pisania pełnej aplikacji.

Wiem o co chodzi, ale to nie zmienia faktu, że to co napisałem jest frameworkiem (mocniej lub luźniej powiązanych ze sobą klas) pomimo tego, że nie ma jeszcze kontrolera, który ułatwia pisanie aplikacji. Zależy kto jak rozumie zasadę działania kontrolera. Dla mnie front controller ma odpalać główne akcje.

Cytat(devnul @ 22.02.2007, 19:32:58 ) *
(...)a co do tematu to chyba na wortalu był jakis artykuł na ten temat.

Wiem, czytałem dużo artów ale każdy ma inne podejście do tego.

Zastanawiam się czy zamknąć wszystko w jednej klasie czy utworzyć klasy:

Router - posiadałaby metodę pobierającą z urla nazwę: kontrolera, modułu, akcji i parametry oraz metodę tworzoną urla na podstawie otrzymanego tokenu

Dispatcher - na podstawie otrzymanego tokenu (token byłby tablicą asocjacyjną zawierającą nazwę kontrolera, modułu, akcji i parametry), który odpalałby odpowiednią akcje..
LBO
Podziel na klasy. Dzięki temu podmieniając np. Router, będziesz mógł parametry pobierać np. z konsoli a nie url'a. Tak samo dispatcher, podmieniając go akcją nie musi być metoda klasy Kontrolera, a np. klasa w folderze kontrolera biggrin.gif
DeyV
kontroler to serce frameworka MVC. To może i byłaby prawda - a i tak nie do końca.
Tak więc takie ironiczne podejście jest co najmniej nie na miejscu.

Zobacz sobie temat o MVC na tym subforum. jest tam sporo rad, jak uruchamiać akcje, jak można dzielić je na moduły itp.
Jarod
Czy obiekt kontrolera akcji powinien dziedziczyć po Front Controllerze czy powinien być odrębną klasą?
LBO
Cytat(J4r0d @ 23.02.2007, 17:14:40 ) *
Czy obiekt kontrolera akcji powinien dziedziczyć po Fron Controllerze czy powinien być odrębną klasą?

Dziedziczyć? A po co w kontrolerze akcji metody dispatch(), addFilter(), registerFilter() etc? smile.gif

Odrębną.
Turgon
Tak, ale po co stosować MVC ? Nie lepiej IPO zastosować ?
Strzałek
Cytat
Tak, ale po co stosować MVC ? Nie lepiej IPO zastosować ?


Bo jest wygodne i ktoś tak chce. Przy okazji mógł byś wytłumaczyć magiczny skrót IPO ?
Turgon
Input Processing Output biggrin.gif Mi to znacznie bardziej pasuje - plus jeszcze event driven i jestem w siódmym niebie smile.gif
Jarod
Cytat(LBO @ 24.02.2007, 01:47:56 ) *
A po co w kontrolerze akcji metody dispatch(), addFilter(), registerFilter() etc? smile.gif


Wiesz jakie metody zawiera bo go już anpisałeś. A ja zastanawiam się jak to zrobić..
LBO
Cytat(J4r0d @ 24.02.2007, 11:39:52 ) *
Wiesz jakie metody zawiera bo go już anpisałeś. A ja zastanawiam się jak to zrobić..


Nie kolego, ja wiem co Front Controller robi... czyli nie to, co Action Controller.
Strzałek
Cytat
Input Processing Output biggrin.gif Mi to znacznie bardziej pasuje - plus jeszcze event driven i jestem w siódmym niebie smilingsmiley.gif


Ok, jakieś linki czy coś? Pierwsze słyszę. Po za tym wnioskując z nazwy. Input - analizujemy żądanie
Processing - realizujemy je
Output - zwracamy wynik.

Jeżeli tak to jest to samo co MVC i we wszystkich aplikacjach, inaczej się nie da. Nic odkrywczego.


J4r0d:

FrontController analizuje input (te twoje linki), i odpala kontroller który później odpala akcje. Controller napewno nie powinien dziedziczyć po FrontController, jeżeli już to na odwrót.
Jarod
Cytat(Strzałek @ 24.02.2007, 13:30:41 ) *
J4r0d:

FrontController analizuje input (te twoje linki), i odpala kontroller który później odpala akcje. Controller napewno nie powinien dziedziczyć po FrontController, jeżeli już to na odwrót.

We wszystkich artykułach, które znalazłem na sieci Front Controller analizuje inputa i odpala odpowiednią akcje.

Strzałek: mógłbyś podać prosty przykład Front Controllera i Action Controllera? Prosty bo chcę załąpać jak to ugryźć. Podglądałem Rapide, ZF i jak na początek nie mogę się w tym odnaleźć..
Strzałek
U mnie nie ma czegoś takiego jak action controller. U mnie jest to mniej więcej tak:


  1. <?php
  2. class FrontController {
  3.  
  4. public function dispatch(){
  5. $controller = $_GET['controller'];
  6. $action = $_GET['action'];
  7.  
  8.  
  9. $this -> perform($contrller, $action);
  10. }
  11.  
  12. public function perform($controller, $action){
  13. $c = new $controller();
  14. $c -> $action();
  15. }
  16.  
  17. }
  18.  
  19. abstract class Controller {
  20. /* .... */
  21. }
  22.  
  23. class NewsController extends Controller {
  24. public function showOneAction(){
  25.  
  26.  /* pobieramy z bazy itp itd. */
  27.  $this -> view -> render('showOne.php');
  28. } 
  29.  
  30. public function showAllAction(){
  31.  
  32.  /* pobieramy z bazy itp itd. */
  33.  $this -> view -> render('showAll.php');
  34. } 
  35.  
  36. }
  37. ?>


Powinno Cię trochę naprowadzić.
mike
~J4r0d mam coś co może Ci pomóc stworzyć swojego kontrolera.
Oto lista rzeczy za które odpowiedzialny jest FrontController w Symfony:
  • Define the core constants.
  • Locate the symfony libraries.
  • Load and initiate the core framework classes.
  • Load the configuration.
  • Decode the request URL to determine the action to execute and the request parameters.
  • If the action does not exist, redirect to the 404 error action.
  • Activate filters (for instance, if the request needs authentication).
  • Execute the filters, first pass.
  • Execute the action and render the view.
  • Execute the filters, second pass.
  • Output the response.
Mam nadzieję że Ci się przyda. Oczywiście masz dowolność w budowaniu swojego, powyższe to tylko przykład (z życia wzięty).
Jarod
@mike_mech: dziękuje zawsze się przyda. Patrząc na przykład Strzałka to każda akcja to osobna klasa dziedzicząca po klasie abstrakcyjnej kontrolera.. Czyli mając w aplikacji 50 akcji to mamy 50 klas dziedziczących po klasie abstrakcyjnej ? :/
SongoQ
@J4r0d Idac wskazowkami @mike_mech rowniez polecam rozejrzec sie po zrodlach SF odnosnie budowy class do akcji. Sa 2 mozliwosci 1 akcja, 1 klasa, 1 plik. Lub wiele akcji, 1 klasa, 1 plik (oczwiscie tutaj jest to uzaleznione od modulu).
Jarod
Jeszcze raz przeglądałem tematy na tym forum dotyczące budowania kontrolera i czytałem m.in. takie wypowiedzi niektórych użytkowników: "Tu powinieneś zastosować forward() zamiast redirect()"

Czym w takim razie (chodzi mi o sposób implementacji) różni się redirect() od forward() ? Przecież oba opierają się o header()
LBO
Mylisz się redirect() to jest przekierowanie przez header, czyli następuje przeładowanie na następną stronę.
Natomiast forward jest wirtualne, bez przekierowania, jedna akcja wywołuje następną.
Jarod
Cytat(LBO @ 11.03.2007, 21:39:28 ) *
Natomiast forward jest wirtualne, bez przekierowania, jedna akcja wywołuje następną.


Czyli podajesz do forward jakiś argument, który jest nazwą akcji do wywołania?
menic
wyglada to mniej wiejcej tak $this->forward('modul', 'akcja', 'parametry'). Tak jest to u mnie zrobione.
Jarod
Ok jeszcze jedno: forward i redirect powinno być w kontrolerze czy routerze?

A jak masz redirect? $this->redirect($url) ?
menic
W kontrolerze. Kontroler pobiera z routera url na który ma byc przekierowany w przypadku redirect
  1. <?php
  2. public function redirect( $sUrl )
  3. {
  4. header( "Location: " . _SPARKLE_WEB . _SEP . swRouter::makeUrl( $sUrl ) );
  5. }
  6. ?>
Ociu
No nie wiem, dla mnie forward jest w kontrolerze, a reditect w Response (wysyłanie nagłówka).
menic
Teoretycznie tak, ale praktycznie jest lepiej w controlerze. Ew. w kontrolerze mozna zrobic nakladke na response winksmiley.jpg
mike
Moim zdaniem (i nie tylko moim bo tak jest w Mojavi, Agavi, Symfony a nawet w CakePHP) controller jest odpowiedzialny zarówno za redirect jak i za forward.

Jest to dla mnie całkowicie naturalne.
forward jets to przerzucenie się na inną akcję podczas tego samego żądania a redirect jest to przeskoczenie na inną akcję z wykonaniem kolejnego żądania. Nie jest to do końca zwrócenie responsea (pomimo tego że wymaga to zwrócenia nagłówków).
Obie powyższe decyzje są decyzjami, które powinien podjąć kontroler i to on powinien się tym zająć.

Za tym rozwiązaniem stoi chmara developerów i jest to rozwiązanie stare i sprawdzone. Nie widzę tu nic nad czym trzeba debatować tongue.gif
menic
@mike_mech: Zgadzam sie. Ale jesli mamy klase typu response która zarzadza w jakis tam sposób wysylanymi nagłowkami to takie redirect() powinno być nakladką na taką klase.
mike
Cytat(menic @ 13.03.2007, 14:03:32 ) *
@mike_mech: Zgadzam sie. Ale jesli mamy klase typu response która zarzadza w jakis tam sposób wysylanymi nagłowkami to takie redirect() powinno być nakladką na taką klase.
Dokładnie. Też twierdzę że technicznie powinien to być mechanizm wykonywany przez Responsea a tylko ewentualnie uruchamiany przez Controllera.
Powinien pójść nagłówek z kodem 302 i wszystko jasne smile.gif

  1. <?php
  2. abstract class sfWebController extends sfController {
  3.  
  4. // ...
  5.  
  6. /**
  7.    * Redirects the request to another URL.
  8.    *
  9.    * @param string An existing URL
  10.    * @param int A delay in seconds before redirecting. This is only needed on
  11.    *  browsers that do not support HTTP headers
  12.    * @param int The status code
  13.    */
  14. public function redirect($url, $delay = 0, $statusCode = 302)
  15. {
  16. $response = $this->getContext()->getResponse();
  17.  
  18. // redirect
  19. $response->clearHttpHeaders();
  20. $response->setStatusCode($statusCode);
  21. $response->setHttpHeader('Location', $url);
  22. $response->setContent(sprintf('<html><head><meta http-equiv="refresh" content="%d;url=%s"/></head></html>', $delay, htmlentities($url, ENT_QUOTES, sfConfig::get('sf_charset'))));
  23.  
  24. if (!sfConfig::get('sf_test'))
  25. {
  26. $response->sendHttpHeaders();
  27. }
  28. $response->sendContent();
  29. }
  30.  
  31. // ...
  32. }
  33.  
  34. ?>
Jarod
@mike-mech: co robi metoda $this->getContext() ?

Jak wygląda metoda clearHttpHeaders() i setHttpHeaders()?
mike
Powyższa funkcja to tylko przykład, który miał mniej więcej zobrazować to co się dzieje. Jest to część fragment klasy sfWebController z Symfony.
Po szczegóły odsyłam do sfWebResponse smile.gif
Ociu
Pewnie jak w większości frameworków:
  1. <?php
  2. public function getContext()
  3. return $this->context;
  4. }
  5. // --------------------
  6. public function setHttpHeaders($strHeaderName, $strHeaderValue)
  7. {
  8. $this->arrHeaders[$strHeaderName] = $strHeaderValue;
  9. }
  10. // --------------------
  11. public function clearHttpHeaders()
  12. {
  13. $this->arrHeaders = array();
  14. }
  15. ?>

smile.gif
Oczywiście nazwy mogą się różnić.
A co do dyskusji. Imho, nie ma nad czym się rozwodzić. Interpretacji jest tyle, ilu programistów. Każdy robi po swojemu.
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.
Invision Power Board © 2001-2025 Invision Power Services, Inc.