Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [ZendFramework] Dziedziczenie po Zend_Controler_Action a metoda init()..., Szukamy pomyslu na nie nadpisywanie init() w klasach podrzędnych...
mxc
post
Post #1





Grupa: Zarejestrowani
Postów: 2
Pomógł: 0
Dołączył: 5.12.2009

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


To mój pierwszy post na forum smile.gif

Wiec Witam Wszystkich ( << O tym ze trafiłem tutaj bo pokochałem tworzenie stron www pisać chyba nie muszę bo widać to po tym zdaniu nawet ^^ )

Ale do rzeczy.. - bawię się Zend_Frameworkiem - pomyślałem ze zrobię sobie moduł 'panel' dzięki któremu będę zarządzał stroną....

No i dobrze... będą kontrolery:
* newsy (do edycji aktualności),
* linki(do edycji linków),
* strony(do edycji podstron takich jak o_mnie, home itp...),
* galeria...
* ipcwp ( i pewnie coś w przyszłości )

pomyślałem ze sobie zrobię Panel_Controller_Action który będzie dziedziczył po Zend_Controller_Action i w init() sprawdzal czy gosc jest zalogowany czy nie...

i teraz problem:
Nie mam pomysłu jak to zrobić w taki sposób by nie móc nadpisać metody init() w klasie Panel_IndexController dziedziczącej po Panel_Controller_Action
Bo jeżeli gdzieś to zrobię to sprawdzanie czy gość jest zalogowany czy nie zostanie nadpisane - czyli leżymy winksmiley.jpg
oczywiście mogę użyć parent::init() i po problemie!
Ale co jak o tym zapomnę ?

Nie jestem obiektowym super programistą...
Ale jestem po "Head First - Design Patterns" <- cholernie polecam książeczkę smile.gif
I wiem ze w "Obiektowe" istnieje jakiś mądrzejszy sposób na wykonanie tego co chce osiągnąć...

Proszę o wskazówki!
Z góry dzięki!

Ten post edytował mxc 5.12.2009, 10:19:23
Go to the top of the page
+Quote Post
Sajrox
post
Post #2





Grupa: Zarejestrowani
Postów: 254
Pomógł: 7
Dołączył: 9.10.2007
Skąd: Poznań

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


Nie wiem czy dobrze zrozumiałem ale ja rozwiązałem to tak:

Sprawdzanie zalogowanej osoby (gośc czy nie gość) ustawiem w pluginie w metodzie dispatchLoopStartup()

Co do Kontrolerów to każdy kontroler dziedziczy po kontrolerze globalnym

  1. class User_OrdersController extends User_InitController {
  2. public function init() {
  3. //Uruchamiamy metodę init z kontrolera globalnego
  4. parent::init();
  5. }
  6. }



Tworzę tutaj metodę init() tak jak w kontrolerze globalnym i w niej wywołuje:
  1. parent::init();


Sam kontroler gobalny wygląda talk:
  1. abstract class User_InitController extends Zend_Controller_Action {
  2.  
  3. public function init() {
  4.  
  5. $userSession = new Zend_Session_Namespace('userSession');
  6. $this->userAuth = $userSession->userAuth;
  7.  
  8. // ...
  9. }
  10. //...
Go to the top of the page
+Quote Post
mxc
post
Post #3





Grupa: Zarejestrowani
Postów: 2
Pomógł: 0
Dołączył: 5.12.2009

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


Dzięki Sajrox za zainteresowanie...
Dobrze mnie zrozumiałeś... aczkolwiek właśnie chcę uniknąć czegoś takiego:

  1. class User_OrdersController extends User_InitController {
  2. public function init() {
  3. //Uruchamiamy metodę init z kontrolera globalnego
  4. parent::init(); //<< dokladnie tego...
  5. }
  6. }


Z założenia ma to być kod wielokrotnego wykorzystania...
Nie chce być zmuszony pamiętać każdorazowo o tej linijce...
Powiem szczerze sam nie wiem dlaczego ^^
Po prostu coś mi mówi ze to nie powinno działać w ten sposób..
...ze istnieje jakieś inne mądrzejsze rozwiązanie winksmiley.jpg
Być może uparciuch ze mnie i szukam problemów na siłę winksmiley.jpg

Ale nie chodzi tylko o auth użytkowników - chciałem sobie dodatkowo dopisać kilka
rzeczy ułatwiających pracę takich jak np. autoDołączanie CSS, JS
Ogólnie chce żeby kontroler globalny zawsze wykonał kilka rzeczy - a dopiero potem pozwolił pracować normalny kontrolerom...

Myślałem nad tym a żeby takie akcje wykonywały się w konstruktorze kontrolera globalnego
ale.... hymmm smile.gif OK - chwila winksmiley.jpg Coś wymyśliłem smile.gif

________________________________________________________________________________
__________
A jednak nie do końca się udało smile.gif

wcześniej też miałem podobny pomysł ale używałem:
  1. parent::__construct()
  2. parent::init()

co wiadomo powodowało ze najpierw wykonywany był init() z Panel_IndexController a dopiero potem init() rodzica
bo Zend_Controller_Action wywołuje
  1. $this->init()

w konstruktorze

Oto i on:
  1. <?php
  2. abstract class My_Controller_Action extends Zend_Controller_Action
  3. {
  4. public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
  5. {
  6. $this->setRequest($request)
  7. ->setResponse($response)
  8. ->_setInvokeArgs($invokeArgs);
  9. $this->_helper = new Zend_Controller_Action_HelperBroker($this);
  10.  
  11. //Tutaj kod :)
  12. echo ' Krok1 >> ';
  13.  
  14. $this->init();
  15. }
  16. }

  1. abstract class My_Panel_Controller_Action extends My_Controller_Action
  2. {
  3. public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array())
  4. {
  5. $this->setRequest($request)
  6. ->setResponse($response)
  7. ->_setInvokeArgs($invokeArgs);
  8. $this->_helper = new Zend_Controller_Action_HelperBroker($this);
  9.  
  10. //Tutaj kod :)
  11. echo ' Krok2 >> ';
  12.  
  13. $this->init();
  14. }
  15. }

  1. class Panel_IndexController extends My_Panel_Controller_Action
  2. {
  3. public function init()
  4. {
  5. echo 'Krok3 ;) ';
  6. }
  7.  
  8. public function indexAction()
  9. {
  10.  
  11. }
  12. }


Uświadomcie mnie dlaczego wynikiem jest:
Krok2 >> Krok3
a nie:
Krok1 >> Krok2 >> Krok3

Ten post edytował mxc 5.12.2009, 11:54:46
Go to the top of the page
+Quote Post
-=Peter=-
post
Post #4





Grupa: Zarejestrowani
Postów: 304
Pomógł: 51
Dołączył: 4.02.2005
Skąd: Kraków

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


Dlatego, gdyż w drugiej klasie nadpisujesz konstruktor tej pierwszej. Konstruktor klasy My_Controller_Action się nie wykonuje.

Nie rozumiem, co chcesz osiągnąć tym sposobem, "zaoszczędzić" 1 linijkę kodu?

Miej zawsze odruch wywoływania w init metody rodzica (parent::init), gdyż nawet jeśli początkowo klasa nadrzędna ma pustą metodę init, to w czasie pisania aplikacji możesz dojść do wniosku, że jednak coś zrefaktorujesz i ją zapełnisz lub też zmienisz klasę bazową - oszczędzisz sobie później nerwów z odnajdowaniem tego, że zapomniałeś wywołać parent::init().

Ten post edytował -=Peter=- 5.12.2009, 12:01:47


--------------------
Go to the top of the page
+Quote Post
seth-kk
post
Post #5





Grupa: Zarejestrowani
Postów: 444
Pomógł: 79
Dołączył: 26.05.2009

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


proponuje jeszcze zapoznac sie z samym oop a zwlaszcza ze slowkiem kluczowym final


--------------------
Go to the top of the page
+Quote Post
darko
post
Post #6





Grupa: Zarejestrowani
Postów: 2 885
Pomógł: 463
Dołączył: 3.10.2009
Skąd: Wrocław

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


Odnośnie sprawdzenia czy user jest zalogowany, akurat są bardziej standardowe rozwiązania pod tytułem Zend_Auth i Zend_Acl. W Zend_Acl zarządzasz rolami, zasobami i dostępem ról do zasobów. W Bootstrapie na podstawie Zend_Auth sprawdzasz czy została określona rola użytkownika i w zależności albo ustawiasz domyślną, albo odczytaną z getStorage()->read()->role.
Najlepiej byłoby napisanie pluginu, do którego, w konstruktorze przekazujesz instancję Twojego Acl'a. W pluginie tym implementujesz jedną metodę o nazwie preDispatch. Metoda ta jest wywoływana za każdym żądaniem, jeszcze przed wywołaniem kontrolera. W ten sposób masz pewność, że plugin zostanie wywołany przy każdym żądaniu. Polecam poszukać informacji o Zend_Auth + Zend_Acl, właściwie od tego są te klasy w ZF.


--------------------
Nie pomagam na pw, tylko forum.
Go to the top of the page
+Quote Post
phpion
post
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




Cytat(seth-kk @ 8.12.2009, 01:53:43 ) *
proponuje jeszcze zapoznac sie z samym oop a zwlaszcza ze slowkiem kluczowym final

Racja, final jest tym, czego potrzebujesz.
  1. final public function init() {}

Dzięki temu nie będzie możliwe nadpisanie tej metody, a takowa próba zostanie wychwycona odpowiednim błędem. Jeśli więc gdziekolwiek w klasach dziedziczących utworzysz metodę init() to otrzymasz błąd.
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 20.08.2025 - 03:15