Skip to end of metadata
Go to start of metadata

<h1>Zend_Controller 2.0 RoadMap</h1>

<h2>Zend_Controller_Action Changes</h2>

<p>Some proposed changes:</p>

<h3>Re-instate noRouteAction()</h3>

<p>Reinstate the noRouteAction() as an empty method (throwing an exception) in Zend_Controller_Action. __call() would then detect method calls ending in 'Action' and call this method.</p>

<p>By itself, this does not represent a BC break; __call() would simply proxy to this method, which would throw the same exception as currently thrown in __call(). Overriding the method would be similar to overriding __call() in current versions.</p>

<h3>Use overloading to access action helpers</h3>

<p>__call() would be modified to determine if a method call is a helper name, and, if so, call its direct() method. __get() would be added, and would do similarly, only it would return the helper directly. This would make calls to helpers much simpler, and make them mimic the behavior of view helpers more directly - leading to better consistency in the framework in general and MVC layer in particular.</p>

<p>As an example,</p>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$this->_helper->redirector('index');
]]></ac:plain-text-body></ac:macro>
<p>would simply become:</p>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$this->redirector('index');
]]></ac:plain-text-body></ac:macro>
<p>As an example showing property access:</p>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$this->_helper->viewRenderer->setNoRender(true);
]]></ac:plain-text-body></ac:macro>
<p>could become:</p>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$this->viewRenderer->setNoRender(true);
]]></ac:plain-text-body></ac:macro>
<p>This would be a slight BC break - but only for developers overriding __call(), and then the BC issues would be limited in scope. $_helper would continue to be registered, so all previous calls to helpers would work. When overriding __call(), you simply wouldn't be able to call helpers as controller methods, since the logic to proxy to the helper broker would not be present.</p>

<h2>Revise Zend_Controller_Plugin_Abstract</h2>

<p>There's no reason for the plugin methods to accept a request object; the abstract already has a getRequest() method. Additionally, an interface should also be created.</p>

<h2>Integrate the Page Controller pattern</h2>

<p>We should explore the possibility of allowing for the Page Controller pattern to be implemented in a way that would support its use with Action Controllers as well as allow it to integrate with the majority of action helpers that currently exist.</p>

<p>This solution would be a viable option for those situations where the cost of having a Front Controller based MVC solution is too high.</p>

<p>A Page Controller solution would offer extreme high availability, more throughput, and a simpler architecture. This would be achieved through having a very lightweight router and dispatcher solution and would leverage the server (ie: ability to route to actual pages on a file system) to handle part of the routing load.</p>

<h2>Zend_Controller_Front improvements</h2>

<h3>Provide a full debugging mode</h3>

<p>Actually, the only thing we can do to debug is to throwExceptions(true). We should add some more methods, those which could use new proposals about Zend_Debug, <a href="http://framework.zend.com/wiki/display/ZFDEV/Zend_Log">Zend_Log</a>, <a href="http://framework.zend.com/wiki/display/ZFDEV/Zend_Exception">Zend_Exception</a> ...<br />
There is <a href="http://framework.zend.com/wiki/display/ZFPROP/Zend_Wildfire_FirebugLogWriter+-+Christoph+Dorn">a proposal</a> for making a plugin dedicated to debug, and an integration of FirePHP, <a href="http://www.firephp.org/Wiki/Libraries/ZendFramework">see here</a>.<br />
Too, it could trigger $viewObject->setStictVars(true) or other things like that that could really help debugging, but without being too heavy (some other frameworks add so much debug infos that the response become unreadable, and takes a while to be dispatched)</p>

<h3>Make the use of the view simpler</h3>

<p>If I want my view in the bootstrap, I have to use something like that :</p>
<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
$vr = Zend_Controller_Action_HelperBroker::geStaticHelper('ViewRenderer'); $vr->init(); $view = $vr->view
]]></ac:plain-text-body></ac:macro>
<p>Wow. I could create it, and pass it back to VR, but it's the same headache...</p>

<p>Why not have a Zend_Controller_Front::setView() method that would do all that work for us (taking care of the case where VR has been disabled) ? Zend_Controller_Front("FC") is used as a "master chief" of all the MVC objects, we actually can ask it for lots of objects (Plugins, Request, Response ...). Shouldn't there be a bridge between FC and the View object, even if FC just proxies it to VR ?</p>

<h4>Paka Yoke filtering</h4>

<p>In an action, _getParam() doesn't do anything that is usefull actually, thinking about direct acces to $_GET, POST ... (am I wrong ?)<br />
Why not create a method aka Zend_Controller_Front::setPakaYokeFilter(Zend_Filter_Input $filter), or something like that. The method should also (as Paka Yoke means), unset all get post cookie original arrays.</p>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jul 03, 2008

    <p>Can we heal Front Controllers singletonitis too?</p>

    1. Jul 03, 2008

      <p>What's that supposed to mean?</p>

  2. Jul 04, 2008

    <p>I think Lars was referring to the fact that Zend_Controller_Front has a protected Constructor method which prevents the use of 2 or more distinct Front Controller instances. At present you can only instantiate one Front Controller instance. If you ever needed two, perhaps because each is a gateway to different parts of a system (maybe an integrated application), you have to go through the whole resetInstance(), set*(), get*(), etc configuration whenever you're switching gateways.</p>

    <p>The impact of changing that would be a pretty obvious backwards compatibility break - there is tons of code out there that has made the mistake of referencing a singleton for plugins (myself included!).</p>

    1. Jul 30, 2008

      <p>Are you implying that you would want to use a front controller & action to dispatch a completely different front controller and action?</p>

      <p>Waht is the use case for having more than one front controller? Wouldnt the above use case be solved by setting up two different bootstraps for the separate systems?</p>

  3. Aug 17, 2008

    <p>+1 for healing front controller singletonitis.</p>

    <p>I think Front Controller could still agregate front controllers. I think it could be achieved by adding a parameter to getInstance().</p>

    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    $default = Zend_Controller_Front::getInstance();
    $another = Zend_Controller_Front::getInstance('another');
    $more = Zend_Controller_Front::getInstance('more');
    ]]></ac:plain-text-body></ac:macro>

  4. Aug 22, 2008

    fc

    <p>Hi all, </p>

    <p>I found this page by accident, while googling "zend_controller". And I think it's a good place to propose some changes. Here's what I propose:</p>

    <p>1. Remove hidden dependency in Zend_Controller_Front::__construct():</p>

    <ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
    protected function __construct()
    {
    $this->_plugins = new Zend_Controller_Plugin_Broker();
    }
    ]]></ac:plain-text-body></ac:macro>

    <p>Maybe a setter/getter method can be added to Zend_Controller_Front so the dependency is injected from within the constructor. This, however, requires some minor changes to the class, for example: $this->_plugin->registerPlugin() becomes $this->getPluginBroker()->registerPlugin()</p>

    <p>2. Zend_Controller_Front::addModuleDirectory($path) adds all the controller directories, but doesn't store the value of $path. Something that's important when working with modules. </p>

    <p>3. Introduce a Zend_Controller_Directory component. See proposal: <ac:link><ri:page ri:content-title="Zend_Controller_Directory - Federico Cargnelutti" ri:space-key="ZFPROP" /></ac:link>.</p>

    <p>4. The Front Controller singleton doesn't allow users to extend the class, so it would be nice if we could move some of its responsibilities to another class.</p>

    1. Dec 16, 2008

      <p>You <strong>can</strong> extend Z_C_F, and I've even blogged on how to do it. It's not easy, but it's possible. I agree in sentiment with the idea of it no longer being a singleton, but I've yet to hear any concrete ideas on how to accomplish this (though I'm actively trying to find one).</p>

  5. Dec 16, 2008

    <p>A few other ideas:</p>
    <ul>
    <li>Remove the hack "direct()" in Zend_Controller_Action_Helper_* and use real Functors (just implement __invoke(), possible in 5.3) so that the plugins can be called with $plugin("foo") directly. This could be done in Zend_View too.</li>
    <li>Zend_Controller_Front: make it a normal object and pass around the instance instead of having the getInstance() mechanism. And no, refactoring it to a multiton (getInstance($name)) would not help</li>
    <li>I really appreciate the __call() thing. Would make controllers more readable.</li>
    </ul>

    1. Dec 16, 2008

      <p>Suggestions on how to push Z_C_F into all the objects would be really nice. I've heard a ton of people request to no longer make it a singleton, but no concrete ideas on how to accomplish this such that elements like view helpers have access to it. I'm personally having trouble visualizing it at this time.</p>

      1. Feb 13, 2009

        <ac:macro ac:name="unmigrated-wiki-markup"><ac:plain-text-body><![CDATA[View helpers have access to front controller because they need request/response object, router object, or a similar one.
        What can be done is to make view helpers ask for their dependencies in the constructor:

        class Zend_View_Helper_Url
        {
        public function __construct(Zend_Controller_Router_Interface $router) {}

        /* wonder if this can be obtained by a bit of Reflection if it's not too slow */
        public static function declareDependencies()

        Unknown macro: { return array('Zend_Controller_Router_Interface'); }

        }

        The view helper broker and action helper broker are given front controller instance when are created during the dispatching properties and are place respectively in view and controller object (sure the process can be decoupled much more). When view/controller request an helper, the broker in charge can pull the objects from the front controller and pass them in the constructor of the helper. This is a basic form of automatic dependency injection.]]></ac:plain-text-body></ac:macro>

  6. Dec 16, 2008

    <blockquote>
    <p>Remove the hack "direct()" in Zend_Controller_Action_Helper_* and use real Functors (just implement __invoke(), possible in 5.3) so that the plugins can be called with $plugin("foo") directly. This could be done in Zend_View too.</p></blockquote>

    <p>Definitely agree with this.</p>

    <p>Also, I think you mean "poka yoke" in your example above.</p>

  7. May 05, 2010

    <p>I would like to suggest the possibility, natively, to structure controllers into subdirectories.</p>

    <p>Currently I'm using a routeShutdown() / routeStartup() of custom Zend_Plugin AND a controller's __call overwrite, to do this in a almost elegant way. Almost because depends of a configurable GET parameter.</p>

    <p>I was reading the Zend_Controller_Action code when I developed the first version of the plugin (enhanced by other programmer), and, if I'm not wrong, shouldn't so difficult to implement this.</p>

    <p>This plugin was not release, but if there is some possibility to implement this resource, I can share it with ZF developers.</p>

    <ul>
    <li>Sorry any wrong grammar</li>
    </ul>