Zend框架:控制器对象中的init()和preDispatch()函数有什么区别?

29

我认为执行顺序是先调用init(),然后是preDispatch(),最后调用action()。

  1. 我的变量在所有操作中都是通用的,那么我应该在init()还是preDispatch()中初始化它们?我看到有人在这两个函数中都进行了初始化。可能根据名称,应该在init()中完成,但preDispatch()中会涉及哪些内容呢?

  2. 在init()和preDispatch()函数调用之间发生了什么?


你是在说控制器对象吗? - Emil Ivanov
@Emil:我已经编辑了这个问题。现在应该很清楚了。 - understack
3个回答

29

首先,对于Zend_Controller_Plugin_Abstract的实例,将调用preDispatch()。在这里,您拥有请求和响应对象,因此可以使用请求中的信息进行一些准备工作或筛选请求。

然后,在构造函数的一部分中,会调用Zend_Controller_Actioninit()方法来帮助初始化控制器,而无需重复构造函数(Zend_Controller_Action::__contruct())的签名。

然后在这里调用控制器的preDispatch()方法。您可以调用$request->setDispatched(false)跳过当前操作 - 不确定是否可以在init()中执行该操作

然后调用您的操作方法(例如viewAction())。在这里,您可以像平常一样从模型中获取内容并填充视图。

因此,区别现在应该是清晰的:

  • 如果您想在所有操作之前执行某些操作-将其放入插件中并使用其中一个钩子(除了preDispatch()外,还有routeStartup其他),
  • 如果您要在控制某个控制器的每个操作之前执行某些操作-请使用initpreDispatch(),
  • 如果只针对单个操作-那么请在该操作中执行。

init()preDispatch()函数调用之间会发生什么?

几乎什么都不会发生 - 将执行preDispatch(),如果您没有调用$request->setDispatched(false)则执行操作。


2
如果您想在控制器中的每个操作之前使用 - init或preDispatch()。实际上,您并没有回答问题本身。从结构上看,在单个控制器上,何时应该使用init()而不是preDispatch()(而不是插件)?例如:我们从未看到AjaxContext助手在preDispatch中被利用,但是在init()中被利用。那么两者之间的概念差异是什么?不是技术上的。如果您明白我的意思。如果您只是可以使用其中一个,那么就没有区别。但我认为有些东西。 - Keyne Viana
关于ajaxContext的提示,我在引用单个控制器示例时查看文档:http://framework.zend.com/manual/en/zend.controller.actionhelpers.html#zend.controller.actionhelpers.contextswitch.ajaxcontext - Keyne Viana
@Emil,作为一个Zend Framework的新手,我想感谢您的回答。 - David 'the bald ginger'
ZF1文档中可以看到:"注意:_forward()方法在init()中执行时实际上无法正常工作,这是两种方法意图的正式化。" - David Harkness

10
  • init()方法主要用于扩展构造函数。通常,您的构造函数应该只设置对象状态,而不执行太多逻辑。这可能包括初始化控制器中使用的资源(例如模型、配置对象等),或分配从前端控制器、引导程序或注册表检索到的值。

  • preDispatch()方法也可以用于设置对象或环境状态(如视图、操作助手等),但其主要目的是决定是否应调度请求的操作。如果不是,则应_forward到另一个操作,或抛出异常。


注意:当从init()中执行_forward时,实际上不会正确工作,这是对这两种方法意图的正式规范化。

0

init(): 在函数之前加载,如果你想在项目的所有函数之前加载它,请将其放在引导类中。如果要在指定类的函数之前加载,请将其放在该类的init()函数中。

preDispatch(): 在前端控制器之前加载。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接