Added by Michael Sheakoski, last edited by Karol Babioch on Mar 04, 2008  (view change)

Labels

 
(None)
Please go to the new MVC Changes page

This proposal is no longer being worked on. Instead direct your attention to the official proposal from Zend:

http://framework.zend.com/wiki/x/kxM

Zend Framework: Changes to Zend MVC Component Proposal

Proposed Component Name Changes to Zend MVC
Developer Notes http://framework.zend.com/wiki/display/ZFDEV/Changes to Zend MVC
Proposers Michael Sheakoski
Christopher Thompson
Revision 1.1 - 1 August 2006: Updated from community comments. (wiki revision: 40)

Table of Contents

1. Overview

This proposal is a combination of several changes to the MVC architecture in ZF:

  • introduction of a Request object which acts a common layer of communication between the bootstrap, Router, FrontController, and ActionController. It is designed in a way to pull data from any source and provide it via a common interface to the MVC components. Currently in this proposal the Zend_Http_Request object provides input from PATH_INFO, GET, and POST data.
  • removal of the DispatchToken. Its functionality is now contained in the Request object.
  • removal of Router-dependant code from the FrontController::dispatch() method. The router is now an optional component that is handled in the bootstrap or in a convenience method such as ::run()
  • removal of URL-related functions from the Router. This is now handled by the Request object.
  • added support for ActionControllers in subdirectories

2. References

3. Component Requirements, Constraints, and Acceptance Criteria

Zend_Http_Request

4. Dependencies on Other Framework Components

5. Theory of Operation

6. Milestones / Tasks

7. Class Index

  • Zend_Request_Interface is a common generic interface that the Router, FrontController, Dispatcher, and ActionController use to to talk to each other. It is designed to interface with any type of input source.
  • Zend_Http_Request builds on top of the Zend_Request_Interface. It contains functions to pull any data from the browser and provide it to the MVC components.
    Some features include:
    • determines important variables on any platform with or without mod_rewrite such as REQUEST_URI and PATH_INFO
    • getParam() automatically falls back to GET/POST variables if a Router is not used or user-defined vars are not set
    • aliases allow you to call your controllers and actions something other than 'controller' and 'action'. This allows for a central location to configure these settings.
    • aliases can be used for more flexible URLs. For example:
      $request->setAlias('controller' => 'c'); $request->setAlias('action' => 'a'); would work with the URL: http://mysite.com/index.php?c=news&a=view
  • Zend_Cli_Request (not created yet) is meant to pull any input from the command-line (args) or keyboard (stdin) and provide it to the MVC components through the Zend_Controller_Request_Interface. This is an example of how the proposed MVC changes allow for much more flexibility by not limiting them to HTTP-specific functionality.
  • Zend_Router_Rewrite (evolution of the RewriteRouter, for mapping PATH_INFO to a controller/action)
  • Zend_Router_RewriteLite (evolution of the original ZF Router, handles simple routes such as http://mysite.com/ and http://mysite.com/ctrl/act/p1/one/p2/two/pN/N) sites in need of a fast, lean and mean solution would use this as opposed to the more full-featured PathRouter
  • Zend_Router_CliParam (not created yet) would allow you to map command-line parameters or keyboard input to an action/controller. For example, automatic processing of parameters in the GNU "--paramname=value" format, "-f filename", "/C zend", etc...

8. Use Cases

This is perhaps how an intermediate / advanced user would use it:

And this would be the beginner approach:

9. Class Skeletons

Download the working prototype here: [Zend_Db_Adapter_Odbtp_Mssql^mvc_working_prototype.zip]


This is shaping up nicely. Two quick Qs:-

  • Did you decide to remove the __get / __set methods for the request properties intentionally? It's not a real deal-breaker if they don't exist, however would be a convenience to the component
  • The proposed Front Controller still - IMO - suffers from a request object being pushed into it, rather than having it passed via the constructor. It's splitting hairs, but I may wish to set up my own 'request' property within a subclassed Zend_Controller_Action and any value I populated the public $request property with would be overwritten by the Front Controller. Could you change the code to read simply

    and then the default constructor for Zend_Controller_Action could then be

Hello Simon,

For _get/_set do you propose they be wrappers for getParam/setParam? This would seem to make the most sense.

As for passing $request to the Action constructor that does seem to make sense. I wasn't sure if the constructor was reserved for any other uses so I left it alone initially.

Indeed, those _get/_set would map to those methods in an ideal world.

Simon, I was thinking about it and passing the $request to the constructor is not necessarely a good idea. It might be better off going through a method such as $controller->setRequest($request) because the developer may want to use the constructor to initialize the controller for their own needs such as setting up global views/templates, db connections specific to the controller, etc... What are your thoughts?

I didn't see that as a huge problem as the Zend_Controller_Action is an abstract class and in most cases the developer will be customising the Action as they see fit anyway.

So I may simply leave the constructor along, but someone else may choose to customise AND retain existing functionality:-

I'd enforce the interface for the constructor, though.

View the rest of this thread. Most recent comment: Sep 12, 2006
11 more comments by: Michael Sheakoski, Christopher Thompson

It might be useful to add an optional $default parameter to the getQuery(), getPost() etc methods rather than having null all the time.

Also, I might be wrong here but since 'null' is being returned as default, would it be better to use isset() instead of array_key_exists()? I was under the impression that language constructs are more efficient than functions. I suppose it's only marginal and not worth worrying about?

Richard, good looking out on isset(). As far as NULL vs $default, I was coming from the direction that if a value did not exist it is considered NULL and not FALSE which would be reserved more for an error. NULL still converts to a boolean FALSE in a non-strict comparison which most people use: if (!$requst->getQuery('loggedIn'))

Unknown macro: { do this; }
http://www.php.net/manual/en/language.types.boolean.php

I understand where you are coming from and would be interested in hearing what others have to say about this as well. I am trying to keep things as lightweight as possible and these little things add up. As long as the interface is consistent I personally don't think it is a problem that NULL is returned for values not found.

Oh I think I read your post wrong. You want a default parameter such as $request->getQuery('loggedIn', false) ?

In the above post I was wrongly thinking you wanted something like $request->setDefaultNotFoundValue(false)

Yeah, the optional parameter, $request->getQuery('loggedIn', false).
I'd have to make wrappers for it if you didn't, and I would presume a lot of developers would find it useful too

I'm not sure why "added support for ActionControllers in subdirectories" is part of this proposal when the rest of it is to do with a Request object and the ramifications on the Router.

Also what are the proposed changes to Zend_Controller_RewriteRouter to create Zend_Router_Rewrite? Removal of detectRewriteBase() and fix up route() to not use $_SERVER but use a Zend_Request_Interface instead?