Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [ZF]Własny dispatcher lub przekierowanie na jeden kontroler.
Forum PHP.pl > Forum > PHP > Frameworki
golaod
Witam serdecznie.

Zacząłem korzystać z ZF kilka dni temu i jak rozumiem większość klas w tym frejmłorku tak nie mogę znaleźć odpowiedzi na moje pytanie.

Chcę rozwiązać taki problem:
Będzie kilka linków które rzeczywiście będzie odwoływać się do konkretnych kontrolerów i akcji. Jednak chcę mieć też możliwość przekierowania całej reszty na jeden kontroler. Tzn np. strona.pl/kontakt/formularz to przykład konkretnego kontrolera i metody, natomiast strona.pl/abc/def/ziuta to coś co bym chciał przekierować np. do kontrolera general/index(abc,def,ziuta).

Czytałem trochę o routerze w zendzie, tym zwykłym i regex, coś tam popatrzyłem w dispatcher i zgubiłem się... Ktoś ma jakiś pomysł ? Może inny niż to co ja znalazłem ?
zend
Jak się już zdecydujesz opisać dokładniej problem to postaram się pomóc, a narazie z tego co zrozumiałem to strona.pl/abc/def/ziuta - w tym chcesz wybierać kontroler i akcje zależnie od parametrów, możesz to ustawić w pluginie który podpinasz do frontControllera pluginy możesz też użyć routera

Zdefiniuj problem dokładniej to pomoge
golaod
Cytat(zend @ 2.04.2010, 21:50:43 ) *
Jak się już zdecydujesz opisać dokładniej problem to postaram się pomóc, a narazie z tego co zrozumiałem to strona.pl/abc/def/ziuta - w tym chcesz wybierać kontroler i akcje zależnie od parametrów, możesz to ustawić w pluginie który podpinasz do frontControllera pluginy możesz też użyć routera

Zdefiniuj problem dokładniej to pomoge


Cóż, no ja myślałem, że to wystarczająco prosto napisałem.

Sprawa wygląda tak(dokładniej).
Mam przypuśćmy dwa kontrolery - Viewer i General.
General ma takie metody about,faq,contact.
Mogą pojawić się dodatkowe kontrolery które będą sprawdzane normalnie: "kontroler istnieje to go wywołaj"

Viewer to kontroler zbiorczy odpowiedzialny za wyświetlanie informacji. Ktoś chce np. wpisać strona.pl/niebieski/gruby i dispatcher lub router przekieruje go do kontrolera Viewer z metodą initial/index(bez znaczenia) wraz z tymi parametrami. Podobna sytuacja będzie np. przy strona.pl/wroclaw czy np strona.pl/okazjonalne/stare. Bez znaczenia co wpiszę, chodzi o to by po prostu rzeczy które NIE są kontrolerem i/lub metodą, były przekierowane do kontrolera który ja wskażę.
viking
  1. $frontcontroller
  2. ->setDefaultModule('module')
  3. ->setDefaultController('controller')
  4. ->setDefaultAction('action');
zend
Robisz statyczny routing dla tych about,faq,contact, dla innych kontrolerów które dodasz też bedziesz musiał dodać statyczny routing, natomiast dla reszty dajesz regułę "*" i ustawiasz kontroler na View

Ja taki problem rozwiązywałem też poprzez poprzedzanie wszystkich adresów które mają wkończyć w tym "wszystko obsługującym" kontrolerze przedrostkiem pl
/pl/:category_url/:content_url ominalem w ten sposób konieczność dodawania statycznego routingu dla wszystkich pozostałych kontrolerów. Regex'y są moim zdaniem najgorszą (najwolniejszą) opcją. Ale zrobisz jak Ci pasuje smile.gif
golaod
Cytat(zend @ 3.04.2010, 18:47:42 ) *
Robisz statyczny routing dla tych about,faq,contact, dla innych kontrolerów które dodasz też bedziesz musiał dodać statyczny routing, natomiast dla reszty dajesz regułę "*" i ustawiasz kontroler na View

Ja taki problem rozwiązywałem też poprzez poprzedzanie wszystkich adresów które mają wkończyć w tym "wszystko obsługującym" kontrolerze przedrostkiem pl
/pl/:category_url/:content_url ominalem w ten sposób konieczność dodawania statycznego routingu dla wszystkich pozostałych kontrolerów. Regex'y są moim zdaniem najgorszą (najwolniejszą) opcją. Ale zrobisz jak Ci pasuje smile.gif

Rozwiązanie dobre, choć jak widzisz muszę statycznie do configa wprowadzać kolejne kontrolery. Mi bardziej chodzi o takie "udoskonalenie" dispatchera na zasadzie brak_kontrolera - > przekieruj do zbiorczego.

Cytat(viking)
  1. $frontcontroller
  2. ->setDefaultModule('module')
  3. ->setDefaultController('controller')
  4. ->setDefaultAction('action');


Pewnie napisałeś coś o co mi właśnie chodzi. Problem jest taki, że z ZF dopiero zaczynam i jedyne z czego ja korzystam to gotowy skrypt wygenerowany przez ZF tool ( przykład z quick start ). Nie wiem gdzie tam obsłużyć frontController.
zend
  1. $f = Zend_Controller_Front::getInstance();
  2. if($f -> getDispatcher() -> isDispatchable($request) == false)
  3. {
  4. $request -> setControllerName('xxx');
  5. }


Proszę bardzo smile.gif Ten kod umieszczasz w pluginie (w metodzie preDispatch) który rejestrujesz w frontControllerze

Edit
zend framework plugins
golaod
Dziękuję zend za odpowiedź, lecz chyba nie doczytałeś mojego posta. Napisałem, że aplikacji z ZF nie składam sam od początku tylko mam wygenerowaną przez ZF-tool.

Rozumiem zatem, że to o czym piszecie muszę dodać gdzieś w pliku index.php który wygląda tak:
  1. <?php
  2.  
  3. // Define path to application directory
  4. defined('APPLICATION_PATH')
  5. || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
  6.  
  7. // Define application environment
  8. defined('APPLICATION_ENV')
  9. || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));
  10.  
  11. // Ensure library/ is on include_path
  12. set_include_path(implode(PATH_SEPARATOR, array(
  13. realpath(APPLICATION_PATH . '/../library'),
  14. )));
  15.  
  16. /** Zend_Application */
  17. require_once 'Zend/Application.php';
  18.  
  19. // Create application, bootstrap, and run
  20. $application = new Zend_Application(
  21. APPLICATION_ENV,
  22. APPLICATION_PATH . '/configs/application.ini'
  23. );
  24. $application->bootstrap()
  25. ->run();

Wybaczcie lecz po prostu nie rozumiem samego jądra tego frameworka za dobrze.
zend
  1. class Application_Controller_Plugin_MyDispatcher extends Zend_Controller_Plugin_Abstract
  2. {
  3.  
  4. public function preDispatch(Zend_Controller_Request_Abstract $request)
  5. {
  6. $f = Zend_Controller_Front::getInstance();
  7. if($f -> getDispatcher() -> isDispatchable($request) == false)
  8. {
  9. $request -> setControllerName('xxx');
  10. }
  11.  
  12. }
  13.  
  14. }
  15.  
  16. class Bootstrap {
  17.  
  18. protected function _initMyDispatcher()
  19. {
  20. $f = $this -> bootstrap('frontController') -> getResource('frontController');
  21. $f -> registerPlugin(new Application_Controller_Plugin_MyDispatcher());
  22. }
  23.  
  24. }


Klase Bootstrap musisz odnaleźć winksmiley.jpg w projekcie i wstawić tą metodę co napisałem, plugin też na sam początek możesz umieścić w tym samym pliku co klasa z bootstrapem

Albo wstaw do konfiguracji autoloadernamespaces.application = "Application_" utworz plik MyDispatcher.php w library/Application/Controller/Plugin/ który sam musisz sobie oczywiście stworzyć
golaod
Cytat(zend @ 3.04.2010, 20:32:02 ) *
  1. class Application_Controller_Plugin_MyDispatcher extends Zend_Controller_Plugin_Abstract
  2. {
  3.  
  4. public function preDispatch(Zend_Controller_Request_Abstract $request)
  5. {
  6. $f = Zend_Controller_Front::getInstance();
  7. if($f -> getDispatcher() -> isDispatchable($request) == false)
  8. {
  9. $request -> setControllerName('xxx');
  10. }
  11.  
  12. }
  13.  
  14. }
  15.  
  16. class Bootstrap {
  17.  
  18. protected function _initMyDispatcher()
  19. {
  20. $f = $this -> bootstrap('frontController') -> getResource('frontController');
  21. $f -> registerPlugin(new Application_Controller_Plugin_MyDispatcher());
  22. }
  23.  
  24. }


Klase Bootstrap musisz odnaleźć winksmiley.jpg w projekcie i wstawić tą metodę co napisałem, plugin też na sam początek możesz umieścić w tym samym pliku co klasa z bootstrapem

Albo wstaw do konfiguracji autoloadernamespaces.application = "Application_" utworz plik MyDispatcher.php w library/Application/Controller/Plugin/ który sam musisz sobie oczywiście stworzyć



Pierwsze rozwiązanie działa dobrze jednak jest jedno "ale". Jak niby są przekazywane argumenty do metody i jak je odczytać ? Z tego co zauważyłem. Wygląda to trochę źle. Dla linku index.php/1/2/3/4/5 $request wygląda tak:
Kod
["_requestUri":protected]=>
  string(37) "/public/index.php/1/2/3/4/5"
  ["_baseUrl":protected]=>
  string(27) "/public/index.php"
  ["_basePath":protected]=>
  NULL
  ["_pathInfo":protected]=>
  string(10) "/1/2/3/4/5"
  ["_params":protected]=>
  array(4) {
    ["controller"]=>
    string(1) "1"
    ["action"]=>
    string(1) "2"
    [3]=>
    string(1) "4"
    ["module"]=>
    string(7) "default"
  }

Nie powinno się chyba 1 i 2 przypisać do kontrolera i akcji tylko być traktowane jako argumenty. I wciąż pozostaje pytanie jak te argumenty wyciągnąć. (dodam, że liczba argumentów będzie zmienna)
zend
  1. public function preDispatch(Zend_Controller_Request_Abstract $request)
  2. {
  3. $f = Zend_Controller_Front::getInstance();
  4. if($f -> getDispatcher() -> isDispatchable($request) == false)
  5. {
  6. $c = $request -> getControllerName();
  7. $a = $request -> getActionName();
  8. $request -> setControllerName('xxx');
  9. $request -> setParam($c , $v);
  10. }
  11.  
  12. }


  1. $id1 = $this -> _getParam('1' , false);
Tak pobierasz parametry w kontrolerze
golaod
Cytat(zend @ 5.04.2010, 18:09:45 ) *
  1. public function preDispatch(Zend_Controller_Request_Abstract $request)
  2. {
  3. $f = Zend_Controller_Front::getInstance();
  4. if($f -> getDispatcher() -> isDispatchable($request) == false)
  5. {
  6. $c = $request -> getControllerName();
  7. $a = $request -> getActionName();
  8. $request -> setControllerName('xxx');
  9. $request -> setParam($c , $v);
  10. }
  11.  
  12. }


  1. $id1 = $this -> _getParam('1' , false);
Tak pobierasz parametry w kontrolerze

Fajnie pięknie tylko chyba coś tu nie gra. Jak daję sobie w kontrolerze:
  1. print_r($this->getRequest()->getParams());

to otrzymuję:
Kod
[controller] => 1
    [action] => 2
    [3] => 4
    [module] => default
    [1] => 2

Ok niby dodało to 1 i 2 choć tak jak wcześniej brakuje 5 - to raz. Dwa, raczej chciałem osiągnąć rezultat, że każda cyfra jest jako osobny argument zamiast index asocjacyjny=>wartosc,index=>wartosc. W Zendzie nie da się w ten sposób argumentów podawać ?
zend
Są 2 wyjścia
1) podajesz pare klucz => wartość np index.php/user/benek/relative_id/2
2) ustawiasz routing /:controller/:action/:user/:relative_id
mozesz też /:param1/:param2/:param3/:param4 ale musisz w tym miejscu uwzględnić maksymalną ilość parametrów jakie możesz mieć w url'u

Klucze nie są kolejnymi indexami zaczynającymi się od zera, tylko parami klucz => wartość, 5 nie widzisz dlatego że jest to klucz dla którego nie podałeś wartości

Edit
Obiekt Request'u nie ma w sobie poprawnych danych dotyczących aktualnego kontrolera, choć ten jest wywoływany, zgłoszę to w najbliższym czasie
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.