Most info classifies access to data as a subset of the model, but that does not work with collections, such as a list of pages. Are databases supposed to be handled by collections which insert the data into the models? Where ultimately does the member name to database field knowledge reside?
Why would you use a repository rather than, for example, a data mapper with an included collection? I don’t understand what purpose a repository serves vs. an object that handles the database and returns arrays itself.
How do I make the view encapsulated? For example, a ton of sources may want to collaborate to route a particular view. The controller action may have a default view type and it may be overridden by model preferences or user preferences or the type of client.
How can you make a view independent of model and controller if it receives its variables from them? Is this a case of making an interpreter to translate similar to how you handle a database? Wouldn’t the interpreter have to interact with the interfaces of model. view, and controller?
How do I make the view encapsulated? For example, a ton of sources may want to collaborate to route a particular view. The controller action may have a default view type and it may be overridden by model preferences or user preferences or the type of client.
Really, in MVC the controller (unless you mean front controller…) does not do view selection. On the web, this tends to happen because the controller is often used as an entry point to the MVC triad but it’s not something defined by the pattern itself. Also, the view:controller relationship is 1:1. This type of code:
class UserController {
public function index() {
$this->template = 'userlist.tpl';
}
public function delete($userId) {
$this->model->user->delete($userId);
$this->template = 'userlist.tpl';
}
public function edit() {
$this->template = 'useredit.tpl';
}
public function save() {
$this->model->user->save($_POST);//using post here for ease of demonstration
$this->template = 'updated.tpl';
}
}
Goes against the basic separation of concerns MVC advocates. This is another messy attempt at simplification used by a lot of “MVC” frameworks. It causes more problems than it solves.
Instead, you should do this:
class Controller {
public function __construct(View $view) {
$this->view = $view;
}
}
class UserListController extends Controller {
public function delete($userId) {
$this->model->user->delete($userId);
}
}
class UserEditController extends Controller {
public function save() {
$this->model->user->save($_POST);//using post here for ease of demonstration
}
}
Notice how the controller only deals with user actions? Read the definition of “Controller” again and it will make a lot more sense.
How can you make a view independent of model and controller if it receives its variables from them?
The first step is realising that in MVC, the view has direct access to the model. Something which is not recognised in most “MVC” frameworks. This removes any model:view binding logic from the controller so is a step in the right direction. Of course the problem of the view being linked to a model remains. But that is part of the pattern. To get around it you can implement an MVC variation such as MVVM (I explored the idea here, if you’re interested)
What I mean is that many objects will have a say in routing a view, but you probably got that. As I understand what you are saying, any “action” related routing is handled by the controller being specific to a view, and any model related routing can be read by the view anyway.
That certainly explains much of what confuses me about MVC. I probably want to use a more appropriate structure then, and what you linked is interesting. Why do many want to use a paradigm that says nothing about either databases or templates, the most important dependencies of PHP apps?
That certainly explains much of what confuses me about MVC. I probably want to use a more appropriate structure then, and what you linked is interesting. Why do many want to use a paradigm that says nothing about either databases or templates, the most important dependencies of PHP apps?
It’s not that MVC isn’t appropriate, it’s probably just that people don’t consider alternatives because MVC is so popular. It’s a self-fulfilling prophecy
I suppose because while MVC says nothing about whether you should use templates or databases it allows easy integration of them. The problem is, people seem to apply an overly simplified model = database, template = view approach which loses many of the benefits MVC tries to offer (especially when the view can’t access the model).
The approach I’m working on is called EDMVC – Event Driven Model View Control. One problem with MVC discussions is that terms get overworked - there are multiple types of controllers and models, and view vs. template gets conflated too often.
In EDMVC there are three dispatchers for each major section of concern -
EventDispatcher - control concerns.
DataDispatcher - model concerns.
ResponseDispatcher - view concerns.
The dispatchers are gateways to their areas of responsibility. For example, when the event dispatcher needs to see the page routing table it asks the data dispatcher. That dispatcher chooses whether it is appropriate to run a database query or fetch from cache.
Control is broken up into events. Events can be a page - a block on a page - or system events (user authentication). They go onto a queue that the event dispatcher resolves. These events are what other systems call controllers. They do their thing, get a model for it and pair it up to a response.
The views can be html, pdf, javascript snippets, depending on the request disposition. The event doesn’t need to be aware of it, the response dispatcher chooses the exact view based on the circumstance of the request.
Similarly the data dispatcher picks a model based on what was asked for.
The virtual web platform solves many of these problems for you.
The 1:1 ratio of the MVC framework is why I merged the View and the Controller into a single object called a widget. The Widget grabs any model it chooses to work with and publishes the data for the layout layer which can be overridden by the theme.
Typically there are 2 models created for each database table being accessed. One for accessing multiple records (collections), and one for accessing a single record. The models themselves are not bound to the database in any way so they are free to pull data from any source. The database interaction is all object oriented and database-independent. You get the database from the framework, you get tables from the database, and you get rows from the tables. Widgets simply provide data for the output layer, so layouts can be made for multiple output formats such as html, xml, pdf, etc.
The database system also includes a generic Query object which can be used for building complex queries such as those needed to generate reports. The query object is manipulated to select which tables to pull data from, which rows to select, groupings, functions such as Min, Max, Avg, etc.
Some time ago I discovered a problem with this design when it came to allowing a Widget to process multiple input sources, such as XForm data, Soap requests, HTTP form data, etc. This is the only case where the Controller:View ratio is no longer 1:1. To handle this issue I added a new optional layer called a listener. Listeners are selected via the URL and make it possible to convert any source type into a common format of a task request. The task request is then called on the Widget. In most cases a widget is only processing form data so the additional layer isn’t always needed.
The 1:1 ratio of the MVC framework is why I merged the View and the Controller into a single object called a widget. The Widget grabs any model it chooses to work with and publishes the data for the layout layer which can be overridden by the theme.
This isn’t what I meant. What I meant was there’s always one controller linked to one view at runtime. They are, of course, interchangeable. The same controller class can be used with multiple views but at any one time one controller instance will be linked to one view instance. My argument was against selecting views in the controller, not for merging controllers and views. As Michael hinted at, linking them like this is detrimental to reusability. The reason MVC is split into 3 rather than 2 is to offer this level of interchangeability between the components.
For instance, say you want an AJAX api to an existing HTML page. It’s likely that the view changes, perhaps to output JSON instead of HTML but the controller and the model will remain the same. Or you might have two types of user list, one that normal members see and one that admins see with extra controls. Only the view has changed here.