How do you organize your controllers?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

How do you organize your controllers?

Post by alex.barylski »

Asssuming you use classes and actions map to methods.

Do you partition your controllers by the type of data they return, such as:

Code: Select all

MyController_Html
MyController_Json
MyController_Rest
MyController_Soap
At what point do you use conditional checks in the actions themselves to determine what data to output, for instance would you have a separate AJAX controller or would use use the HTML controller and conditionally check whether to return only the body section or the entire layout and everything?

The primary force pushing me in this direction, is the fact I have managed to factor much of the redundant code into individual base controllers, so deriving one monolithic controller after each sub-class doesn`t make sense, when only one action method requires the functionality in base controller XYZ. Using composition in this regard just feels dirty and doesn`t lend itself to elegant design.

What says youÉ

Cheers,
Alex
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: How do you organize your controllers?

Post by John Cartwright »

I would generally use a protected method in the controller and have 2 seperate action methods setting the appropriate view (which generates the correct output based on the data given).

A very simplified example being:

Code: Select all

class IndexController extends BaseController
{
    public function Login() 
    {
       $data = $this->_login();
       
       $this->view->render('login', 'html');
    }
 
    public function LoginJson() 
    {
       $data = $this->_login();
        
       $this->view->layout = false;
       $this->view->render('login', 'json');
    }    
 
    protected function _login()
    {
        //internal login procedure
    }
}
There is probably a more elegant way to handle this, however, I like having the interface defined explicitly.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: How do you organize your controllers?

Post by Christopher »

PCSpectra wrote:Do you partition your controllers by the type of data they return
I will be the MVC bigot here and point out that Controllers don't return data -- Views do.

Controllers should be divided by they types of Requests they accept. Then you can have a View for each type of output, or a single View and a template for each type of output.
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you organize your controllers?

Post by alex.barylski »

That is an important distinction to make, but...

My view objects are simply a OO interface to a alternative syntax template engine.

Knowing this, are you suggesting I simply switch the template type, if I need to putput RSS feed as opposed to an XHTML formatted LI of articles or blog entries...

Sorry my keyboard sucks so I cannot type equation marks to indicate proper punctuation. :P

EDIT | Lets assume an example, of a

Code: Select all

blog/archives
controller:action pair.

1. Pull on the DB object and select all archived blog entries
2. Create view object and initialize with XHTML template
3. Execute template, inject results into layout, set reponse content

This action is mapped to a URI (obviously) such as www.domain.com/blog/archives.html so would I not just introduce yet another controller:action for something like www.domain.com/blog/archives.rss?

If I use the single controller:action how then, would I determine in the action whether to use an RSS template or XHTML template? If this is done in the view, how would the view know about which to display, as I fail to see any context of RSS or XHTML when using a single controller:action.

This is something that has been bugging me lately...what am I missing?

Cheers,
Alex
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: How do you organize your controllers?

Post by Christopher »

I would just add a parameter to tell the View what to render, like http://www.domain.com/blog/archives/rss or http://www.domain.com/blog/archives/format/json or http://www.domain.com/blog/archives/type/rss or something like that.

Are you rewriting URLs like http://www.domain.com/blog/archives.html to some other URL?
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How do you organize your controllers?

Post by alex.barylski »

I would just add a parameter to tell the View what to render, like http://www.domain.com/blog/archives/rss or http://www.domain.com/blog/archives/format/json or http://www.domain.com/blog/archives/type/rss or something like that.
I did that but I had two issues with it:

1. It introduces an IF statement to the controller -- nothing serious but I'd prefer to keep my controllers as flat as possible. Introduce a new action and the conditional logic is implied rather than explicit.

2. Having a method conditionally check format/output types (whether RSS, XHTML, etc) breaks the SRP I think.

Introducing another controller does cause some duplication but mostly just in querying the model and instantiating the view, maybe 2 or 3 lines or the equivelant of having implemented the original controller as a IF-ELSE statement.
Controllers should be divided by they types of Requests they accept. Then you can have a View for each type of output, or a single View and a template for each type of output.
I think this is a very important point, but technically speaking, having two controller:actions, one which processes RSS request and one that processes XHTML is not exactly breaking this principle. In fact I think it's encouraging it more than having one controller:action accepting an RSS or HTML request and using a conditional to determine view output.

I think were on the same path, but I may have derailed the discussion a bit by suggesting my controllers generate/return content - they do not but I obviously made it sound that way. :)
Are you rewriting URLs like http://www.domain.com/blog/archives.html to some other URL?
Negative. All URI's map 1:1 with a controller:action pair.

Cheers,
Alex
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: How do you organize your controllers?

Post by Christopher »

I definitely don't think you need multiple controllers. As I said, you can do mulitple actions like this:

http://www.domain.com/blog/archivesrss
http://www.domain.com/blog/archivesjson.

Or you can add a parameter that the Controller just passes to the View (no if) like this:

http://www.domain.com/blog/archives/rss
http://www.domain.com/blog/archives/json

I would prefer the latter because the Controller knows less. The View either has a valid output type set or not. If not it shows an error or redirects. The smarts should be in the Model and View.
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: How do you organize your controllers?

Post by josh »

It is relevant to check out how Zend does the context switch action helper http://framework.zend.com/manual/en/zen ... lpers.html
Also, controllers can sometimes output, like the zend JSON helper. While its more correct to bring a 'view' into play I would cringe at the though of creating duplicated views just to repeat 'echo $this->json' [1]

Normally what I'll do is have a saveAction(), this might be called by a form POSTing, or an ajax call, I use zend's convenience method isXhttpRequest(), if it is an ajax call I return the response in JSON, if not I redirect the page, or do whatever.

The zend context switch allows you to have different views

myView.json.phtml
myView.xml.phtml
myview.rss.phtml

and you'd use the JSON view helper to do output, instead of doing output in the controller, which is more correct if the action has multiple contexts.

[1] (if the action does not need to be reusable)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: How do you organize your controllers?

Post by Christopher »

Do you actually use the ContextSwitch helper?
(#10850)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: How do you organize your controllers?

Post by josh »

I've used it before, but not regularly or recently, why?
Post Reply