Как да стартирате едни и същи редове във всички контролери init() функция?

Имам нужда от едни и същи 2 реда във всички мои контролери, всеки контролер има своя собствена логика за стартиране, но тези два реда са общи за всички тях.

public function init()
{
    $fm =$this->_helper->getHelper('FlashMessenger');
    $this->view->messages = $fm->getMessages();
}

Как мога да избегна повтарящ се код?

Актуализация:

Добре, FlashMessenger беше само пример, да кажем, че трябва да напиша ред във всяко действие, с изключение на 'someAction' @ 'someController'. Така че новите общи линии трябва да бъдат.

$this->logger = new Zend_Log();
$writer = new Zend_Log_Writer_Stream(APPLICATION_PATH.'/../logs/log.txt');
$this->logger->addWriter($writer);
$this->logger->log('Some Message',Zend_Log::DEBUG);

Въпросът е къде трябва да поставя тези редове, за да избегна повторението им във всички init() на всеки контролер. Тези редове трябва да бъдат поставени в bootstrap?. Ако е така: Как мога да пропусна редове в журнала за „someAction“. Или трябва да внедря „BaseController“ и да накарам целия си контролер да се простира от него. Ако е така: Как мога да го заредя автоматично? (Фатална грешка: Класът „BaseController“ не е намерен) .


person texai    schedule 18.02.2011    source източник


Отговори (5)


Просто подкласирайте контролера:

class Application_ControllerAction extends Zend_Controller_Action {
    public function init()
    {
        $fm =$this->_helper->getHelper('FlashMessenger');
        $this->view->messages = $fm->getMessages();
    }
}


class IndexController extends Application_ControllerAction {
}

Можете също така да постигнете същото писане на приставка за контролер.

Редактиране:

Плъгините за преден контролер се изпълняват при всяка заявка, точно като Controllers и имат същите методи за закачане:

routeStartup(): prior to routing the request
routeShutdown(): after routing the request
dispatchLoopStartup(): prior to entering the dispatch loop
preDispatch(): prior to dispatching an individual action
postDispatch(): after dispatching an individual action
dispatchLoopShutdown(): after completing the dispatch loop

Освен това можете да проверите параметрите на контролера, за да изпълните кода само при избрани заявки:

if ('admin' == $this->getRequest()->getModuleName() 
&& 'update' == $this->getRequest()->getActionName() ) …
person takeshin    schedule 19.02.2011
comment
Моля, обяснете как би помогнал приставката за контролер - person texai; 19.02.2011
comment
Препоръчвам да използвате помощник за изглед вместо подклас на контролера, тъй като помощниците за изглед са създадени точно за тази цел. Подкласирането на класа Controller е обичаен подход в рамките на други рамки, но Zend предоставя помощната функционалност. Същото важи и за екшън помощниците, между другото. - person Martijn; 20.02.2011

Можете да получите достъп до вашите флаш съобщения чрез (не е необходимо да изпращате нищо от вашия контролер към вашия изглед, всичко е автоматизирано)

$fm = new Zend_Controller_Action_Helper_FlashMessenger();
Zend_Debug::dump($fm->getMessages());

според вас бих препоръчал също така да капсулирате този код в помощник за преглед, както е показано на този сайт http://grummfy.be/blog/191

person JF Dion    schedule 18.02.2011
comment
@Jeff: Благодаря за отговора, но все пак искам да знам как да избегна повтарящ се код във всичките ви контролери. - person texai; 18.02.2011
comment
Зададох подобен въпрос относно това stackoverflow.com/questions/4347965/ - person JF Dion; 18.02.2011
comment
@Jeff: Освен това предпочитам да не пиша ново в изгледите си. - person texai; 18.02.2011
comment
@texai : Мога да разбера вашите предпочитания за кодиране и съм добре с тях, но ако се позовавате на теоретичния модел на проектиране на MVC, контролерите и изгледите могат да извикват модели, така че освен предпочитанията за кодиране, там няма нищо лошо (en.wikipedia.org/wiki/Model_view_controller) - person JF Dion; 18.02.2011
comment
@Jeff: Понякога извиквам статични методи на моите моделни класове от изгледи, но предпочитам да правя new в контролерите. - person texai; 19.02.2011
comment
@Jeff FlashMessenger беше само пример. Зададох нов пример, моля, вижте актуализацията. - person texai; 19.02.2011

Във вашия bootstrap:

protected function _initMyActionHelpers() {
    $fm = new My_Controller_Action_Helper_FlashMessenger();
    Zend_Controller_Action_HelperBroker::addHelper($fm);;
}
person Stephen Fuhry    schedule 18.02.2011
comment
Това с FlashMessenger беше само пример. Моля, вижте актуализацията на въпроса. - person texai; 19.02.2011

Как мога да избегна повтарящ се код?

Напишете свой собствен персонализиран контролер, внедрите го в init метод на този контролер и след това разширете всички контролери в приложението си от вашия персонализиран контролер.

Но подходът с отделен помощник за изглед, както спомена @Jeff (вижте връзката), често се приема като по-добро решение. Във вашия контролер правете само:

$this->_helper->flashMessanger('My message');

и View Helper ще свърши останалото.

person Radek Benkel    schedule 18.02.2011
comment
Това побеждава целия смисъл на действие помощници! от документите: Action Helpers имат за цел да сведат до минимум необходимостта от разширяване на абстрактния Action Controller, за да инжектират обща функционалност на Action Controller framework.zend.com/manual/en/zend.controller.actionhelpers.html - person Stephen Fuhry; 19.02.2011
comment
Не съм казал, че е добро решение. Още - написах, че този помощник за преглед ще бъде по-добър и предложих код, без да е необходимо да използвате init! Но въпросът беше: как да стартирам нещо във всички контролери init функция - и това, което написах, е чист отговор на този въпрос. Така че мисля, че гласуването против мен е несправедливо. - person Radek Benkel; 19.02.2011

Това не е причината за създаването на нов потребителски контролер. Просто добавете този ред към всички ваши init() методи.

$this->view->messages = $this->_helper->getHelper('FlashMessenger')->getMessages();
person KomarSerjio    schedule 18.02.2011
comment
Точно това искам да избегна - person texai; 19.02.2011