-- Nick Lo <[EMAIL PROTECTED]> wrote
(on Wednesday, 06 December 2006, 03:09 PM +1100):
> Aha, now I get it ...so what I CAN do is:

<snip -- code examples>

> So in short init() is a convenience method which is fine. 

Correct. It's to make it easier on you, the developer, so you don't have
to write out that nasty __construct() line. :-)

> I was just uncomfortable with the idea of being forced to use it on
> the basis that things otherwise broke (which they don't - my mistake)
> and that I may forget to properly initialise the parent class.
> 
> Thanks very much for your detailed (and patient) responses, I now  
> follow it a lot more clearly.

No problem! Glad I was able to clarify things.

> >-- Nick Lo <[EMAIL PROTECTED]> wrote
> >(on Wednesday, 06 December 2006, 01:00 PM +1100):
> >>Hi Matthew,
> >>
> >>>init() happens at object instantiation, which happens before
> >>>preDispatch() -- it's basically provided so that you don't need to
> >>>override the constructor, and thus possibly forget to set the  
> >>>request,
> >>>response, and other parameters (as you discovered the hard way).
> >>
> >>It does seem like having init() as a means to bypass the constructor
> >>and also having preDispatch() is possibly a little unintuitive.
> >>Surely init() is a constructor of sorts?
> >
> >It's not meant to bypass the constructor; it's meant as a means to  
> >allow
> >further instantiation actions without needing to override the  
> >constructor.
> >
> >Matt Ratzloff asked "why not declare it final?" My answer to this is
> >backwards compatability; by not declaring it final, developers instead
> >can fix their classes as they start needing some of the functionality,
> >such as access to the request object, instead of having their apps  
> >break
> >entirely due to the constructor now being final. (There were a lot of
> >complaints about this.)
> >
> >>In theory I can set the request and response....
> >>
> >>$controller->setRequest( new Zend_Controller_Request_Http );
> >>$controller->setResponse( new Zend_Controller_Response_Http );
> >>
> >>...as I do the router...
> >>
> >>$controller->setRouter($router);
> >
> >This latter is only in the front controller.
> >
> >>
> >>...but it will still be required to specified in the constructor of
> >>classes overriding __construct...
> >>
> >>parent::__construct( new Zend_Controller_Request_Http, new
> >>Zend_Controller_Response_Http );
> >>
> >>...however at that point the parameters will not be available.
> >
> >Umm... yes, they will, if you define your constructor to follow
> >Zend_Controller_Action's prototype:
> >
> >    public function __construct(
> >        Zend_Controller_Request_Abstract $request = null,
> >        Zend_Controller_Response_Abstract $response = null,
> >        array $invokeArgs = null)
> >    {}
> >
> >then simply do this:
> >
> >    public function __construct(...)
> >    {
> >        parent::__construct($request, $response, $invokeArgs);
> >
> >        // ...
> >    }
> >
> >>It seems that if we have to follow the init() path the manual is
> >>going to have to say something like...
> >>
> >> "If you subclass Zend_Controller_Action you should not override the
> >>constructor instead setup code should go in the init() method"
> >
> >It does say that. In the current manual from subversion:
> >
> >    "While you may override the constructor, we suggest putting any
> >    initialization handling into init() to ensure the request and
> >    response objects are properly registered."
> >
> >>In other words it will need to be a warning. That is where I feel
> >>that init() is unintuitive and most people (I say with hesitation
> >>being a self elected representative) would expect to go with the
> >>constructor for this task.
> >>
> >>Note also that I didn't forget to set the request and response
> >>objects when I overrode the constructor, rather that when I did set
> >>them in the subclass no parameters were available in the controller.
> >
> >You set them improperly, though. You created *new* objects, instead of
> >simply passing in the parameters that were passed to your constructor.
> >
> >>>Theoretically, if something goes wrong during the initialization
> >>>sequence, you could throw an exception, in which case the
> >>>preDispatch()
> >>>will not be called -- this may be handy so that you can, for  
> >>>instance,
> >>>setup your models, etc., and, if unavailable, prevent the action  
> >>>from
> >>>dispatching. preDispatch() might then actually use the models to do
> >>>some
> >>>determination of whether or not to skip the current action.
> >>
> >>I follow the theory and I'd be interested in hearing how others are
> >>using preDispatch and whether their use really does differentiate  
> >>init
> >>() from preDispatch() in the way you mention.
> >
> >Here's how I'm using it in one of my applications. I have this in a
> >Zend_Controller_Action subclass from which my other classes then  
> >derive:
> >
> >    public function init()
> >    {
> >        // Loads the model based on the current action, which will  
> >throw
> >        // an exception if there are issues
> >        $this->loadModel();
> >
> >        // Load up authentication and start it. Again, throws an
> >        // exception if there are issues
> >        $this->getAuth()->start();
> >    }
> >
> >Then, preDispatch() is defined on a per action controller basis. Some
> >may set certain ACLs -- which require that authentication has already
> >begun. Some may query the model based on user information, and  
> >decide to
> >forward to another controller.
> >
> >Which brings up another point: init() should not change the requested
> >action; preDispatch() may do so, forwarding to another action if  
> >certain
> >criteria are not met.
> >
> >Hope this helps answer some questions. I think there's still some  
> >wiggle
> >room inthe API, but many of the decisions have been debated or are  
> >based
> >on user feedback already.
> >
> >-- 
> >Matthew Weier O'Phinney
> >PHP Developer            | [EMAIL PROTECTED]
> >Zend - The PHP Company   | http://www.zend.com/
> 

-- 
Matthew Weier O'Phinney
PHP Developer            | [EMAIL PROTECTED]
Zend - The PHP Company   | http://www.zend.com/

Reply via email to