1) I use a simple homebrew set of classes for some of my MVC stuff, and it relates controller names to action and view names (it's a Front Controller style, similar to Zend). For a generic web site, let's assume it has a home page, privacy policy, contact page and an about page. I don't really want to make separate controllers for all these things, so I'll stick them inside my IndexController
, with function names like actionIndex()
, actionPrivacy()
, actionContact()
, and actionAbout()
.
To go along with that, inside my Views directory I have a directory of templates associated with each action. By default, any action automatically looks for an associated template, although you can specify one if you wish. So actionPrivacy()
would look for a template file at index/privacy.php
, actionContact()
would look for index/contact.php
, etc.
Of course, this relates to the URLs as well. So a url hit to http://www.example.com/index/about
would run actionAbout()
, which would load the About page template. Since the about page is completely static content, my actionAbout()
does absolutely nothing, other than provide a public action for the Front Controller to see and run.
So to answer the core of your question, I do put multiple "pages" into a single controller, and it works fine for my purposes. One model per controller is a theory I don't think I'd try to follow when working with Web MVC, as it seems to fit an application with state much better.
2) For this, I would have multiple controllers. Following the same methods I use above, I would have /admin/dashboard
and /account/dashboard
as you suggest, although there's no reason they couldn't use the same (or portions of the same) templates.
I suppose if I had a gazillion different kinds of users, I'd make things more generic and only use one controller, and have a mod_rewrite rule to handle the loading. It would probably depend on how functionally complex the dashboard is, and what the account set up is like.
3) I find CRUD functionality difficult to implement directly into any layer of MVC and still have it be clean, flexible and efficient. I like to abstract CRUD functionality out into a service layer that any object may call upon, and have a base object class from which I can extend any objects needing CRUD.
I would suggest utilizing some of the PHP ORM frameworks out there for CRUD. They can do away with a lot of the hassle of getting a nice implementation.
In terms of login controller versus user controller, I suppose it depends on your application domain. With my style of programming, I would tend to think of "logging in" as a simple operation within the domain of a User model, and thusly have a single operation for it inside a user controller. To be more precise, I would have the UserController
instantiate a user model and call a login routine on the model. I can't tell you that this is the proper way, because I couldn't say for sure what the proper way is supposed to be. It's a matter of context.
4) You're right about the leeway. You could easily create a controller that handled everything your app/site wanted to do. However, I think you'd agree that this would become a maintenance nightmare. I still get the jibbly-jibblies thinking about my last job at a market research company, where the internal PHP app was done by an overseas team with what I can only assume was little-to-no training. We're talking 10,000 line scripts that handled the whole site. It was impossible to maintain.
So, I'd suggest you break your app/site down into business domain areas, and create controllers based on that. Figure out the core concepts of your app and go from there.
Example
Let's say I had a web site about manatees, because obviously manatees rock. I'd want some normal site pages (about, contact, etc.), user account management, a forum, a picture gallery, and maybe a research document material area (with the latest science about manatees). Pretty simple, and a lot of it would be static, but you can start to see the breakdown.
IndexController
- handles about page, privacy policy, generic static content.
UserController
- handles account creation, logging in/out, preferences
PictureController
- display pictures, handle uploads
ForumController
- probably not much, I'd try to integrate an external forum, which would mean I wouldn't need much functionality here.
LibraryController
- show lists of recent news and research
HugAManateeController
- virtual manatee hugging in real-time over HTTP
That probably gives you at least a basic separation. If you find a controller becoming extremely large, it's probably time to break down the business domain into separate controllers.
It will be different for every project, so a little planning goes a long way towards what kind of architectural structure you'll have.
Web MVC can get very subjective, as it is quite different from a MVC model where your application has state. I try to keep major functionality out of Controllers when dealing with web apps. I like them to instantiate a few objects or models, run a couple of methods based on the action being taken, and collect some View data to pass off to the View once it's done. The simpler the better, and I put the core business logic into the models, which are supposed to be representative of the state of the application.
Hope that helps.