-- 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/