-- Simon R Jones <[EMAIL PROTECTED]> wrote (on Thursday, 14 February 2008, 09:05 AM +0000): > thanks for the reply Matthew > > Can I ask why _forward() stacks and only forwards at the end of the current > controller method? I couldn't find any reference to why it works this way > in the docs so when some of the guys in the office had used multiple > forwards (without returns) the default behaviour was confusing.
When you call _forward(), you're stayinging within the current request cycle, but indicating you have another action to call. The way the request cycle works is roughly as follows: front controller routing dispatch loop resolve request to controller and action dispatch action run action in controller send output When you call _forward(), you're simply setting a token in the request object; the dispatch loop checks for this token, and if set, it then performs another iteration of the loop. Since the setting of the token is happening within a method call, within another method call, within yet another method call.... you can't simply call 'continue' and have it work; you're simply in the wrong lexical scope. Additionally, as I noted in my original reply, you can't have a called function force the calling function to return: function foo() { bar(); print 'foo'; } function bar() { return; } There's simply nothing you can call in bar() that will prevent foo() from printing 'foo'... short of a die() or exit(), and those aren't desired in this case. As for the manual, perhaps I can make it clearer, but it reads: "If called in preDispatch(), the currently requested action will be skipped in favor of the new one. Otherwise, after the current action is processed, the action requested in _forward() will be executed." The part that is important here is "*after* the current action is processed" (emphasis mine) -- i.e., the new action will only be processed after the current action is *done*. > On 13 Feb 2008, at 19:36, Matthew Weier O'Phinney wrote: > > > > Correct -- you need to return. I actually usually write it as: > > > > return $this-> _forward('index', 'login'); > > > > as the return value of an action is ignored anyways. > > > > The reason it works this way (i.e., you need to return when forwarding) > > is because you can't have a called function force the calling function > > to return -- it's a language limitation. > > > > > Further to this, if the above is the recommended way to forward and quit > > > the current method then this of course becomes problematic if I > > > abstracted > > > the login check. I.e. if I called a function to do something like: > > > > > > $this-> checkLogin(); > > > > > > And the function checkLogin() did the necessary ACL check and also > > > included > > > the forward() - to avoid DRY. > > > > Unfortunate, but necessary. I typically have methods like this return a > > boolean, so I can then do something like this: > > > > if (!$this-> checkLogin() { > > return $this-> _forward('index', 'login'); > > } > > > > -- Matthew Weier O'Phinney PHP Developer | [EMAIL PROTECTED] Zend - The PHP Company | http://www.zend.com/