is it usual to use controllers in models?
then you have to include the controller in the model?
Models should not be using controllers.
To clarify, using the MVC pattern, the user communicates with the controller which manipulates the model which dispatches its results to the view back to the user.
Image taken from The Model-View-Controller (MVC) Design Pattern for PHP
Update to Doug's response:
The most logical way to explain how the components work is by starting from the model, then going through the controller, and finally reaching the view. And "MCV" would not have been nearly as appealing a name to the ear as "MVC."
Taken from Chapter 1 of Beginning ASP.NET MVC 1.0 by Simone Chiaretta and Keyvan Nayyeri.
No it is not common. You should never have to use your controllers from your model.
If you feel the need to, it probably means code that is currently in your controller should live in a shared library, or actually be in the model to begin with.
It is of course proper to use a model from a controller.
Update
Code that doesn't directly relate to a specific database table/record (model), or doesn't directly respond to a user's action (controller), would be a good candidate for a utilities or library file.
This is more normal, and where you load it depends on if you are using a framework or not. If it just your custom app, you can just do a require_once in your model and use the utility methods from there.
Related
This is a question about theory, so there is no need for code snippets.
I built a router that, as a typical router does, dispatches a controller based on the URL. The workflow is something like this:
Router dispatches controller and instantiates it
Controller renders a view
User interacts with the view
Controller updates model based on user interaction
Model returns the new state of the data to the controller
Controller updates the view based on new data
So basically, the controller is the starting point and the link between the model and view. The model and view never directly interact with each other. The controller is the workhorse and has most of the code.
Now, that is all good and I get it. The confusion comes when I read articles about MVC design patterns and realize what they describe is not what I just described above. It seems like, in the pattern you start at the view. The view talks directly to the model and the controller accepts user interaction to update the model.
So, what I'm doing may involve models, views and controllers, but its not strictly the MVC design pattern. I did read one article where they called what I first described as CAV, controller action view.
My question is, what is it that I'm describing? I don't want to keep referring to it as MVC if its not actually MVC. From what I read true MVC was birthed in the 70's. Things have changed since then. Perhaps what I'm doing is some evolved version of MVC, but not MVC in its strict form. Is there another name for it so I can stop confusing myself, and others, by calling it MVC?
I think its language (technology) dependent.
You tagged your question with the php tag, so I suppose you're developing applications using this language. In a classic PHP application, the view can't get updates from the model (in fact, this more related to the PHP language being executed only on the server).
First, the entire application is launched for each request and is terminated when all the response has been sent. So, the router is called for each request.
Then, the router execute the controller which have to handle the request (according to routing rules).
The request being for reading or writing does not modify this behavior.
If you want to allow the view to ask for data modification approval to your controller, you may need to use some client-side programming language (Javascript). So, you may use a REST API to handle communication between the model and the view.
To answer your question, I think you can't implements a pure MVC design pattern on a client-server model without using a programming language on the client.
Even I faced this confusion previously. In the original form, View did interact with the controller. They followed the observer-observable pattern. This was how MVC was conceived in SmallTalk. However, The version of MVC that you are talking about is actually a modern version of it and is used in most frameworks. It sort of has became a standard. I do not know of any other term for it. In this version, the controller is actually a bridge between view and model. However, both of the patterns achieve the desired objective of separation of concerns.
How will you write your controller in MVC pattern without PHP frameworks?
This is the simplest version of my controller,
//Controller
class Controller
{
private $model;
public function __construct($model){
$this->model = $model;
}
public function clicked() {
$this->model->string = "Updated Data, thanks to MVC and PHP!";
}
}
As you can see that only model is passed into my controller as its dependency.
This is how I understand the controller in MVC pattern which can be referenced in these following articles,
https://r.je/views-are-not-templates.html
http://www.sitepoint.com/the-mvc-pattern-and-php-1/
PHP framework developers probably disagree with this, because as most frameworks seem to be MVC, but probably are Model 2.
In a Model 2 application, requests from the client browser are passed
to the controller. The controller performs any logic necessary to
obtain the correct content for display. It then places the content in
the request (commonly in the form of a JavaBean or POJO) and decides
which view it will pass the request to. The view then renders the
content passed by the controller.
So if we are going to put these frameworks aside, how do you do your controller then?
I've written a series of articles for writing MVC applications, inspired by one of the links you posted. Among those there is an article about Controllers:
Controllers are taking SRP seriously
Have a read at it first.
So if we are going to put these frameworks aside, how do you do your
controller then?
My controllers don't have a reference to the view. They only update the model as shown in your code sample, and I think that's the right way to do. Controllers shouldn't contain binding logic to the view. Instead, the view gets its data from the model (see The View gets its own data from the Model where I also explain the advantages of such a design).
Controllers can consume as many dependencies as they want (they might need more than just the model injected), but if you follow SRP closely, controllers won't need a lot of dependencies.
In most popular frameworks, you see a controller with a bunch of actions and binding logic for view rendering; I instead separate all these actions into separate controllers so that I have a 1:1 relationship between controller and view. This allows me to have controllers without binding logic to the view (see link above for detailed explanation on how I do that). My Controllers also follow SRP more closely this way.
When I said above, that the controller updates the model, beware that MVC Models are not just Domain Models. In addition to Domain Models, View Models store the state that the view needs for rendering, e.g.: the view allowing to update an entity like let's say a User, needs to know which user needs to be updated (again, read articles for more detailed explanations). My Controllers have thus in most cases at least two dependencies,
a domain model (most frequently an ORM instance) allowing me to update the datasource
a view model allowing me to update the application state (like which user is to be updated, search filters, ...) necessary for view rendering
I'd not seen Model 2 before this question, but as far as I can tell it is just a Java-specific approach to MVC, it isn't a separate design pattern as such.
You've not really explained why you think the PHP frameworks you mentioned aren't following MVC, in ZF at least it is quite common practice for dependencies to be passed in via. a controller's constructor as you have in the example from your own framework.
It's easy to fall down the rabbit hole with design patterns, really a lot of it is down to interpretation. Just because your implementation of a pattern isn't the same as another, doesn't necessarily mean the other implementation is wrong.
I have the following data flow for a simple login form.
User access controller PHP file. Controller includes model.php and view.php
User submits form, controller sends POST data to model methods, and gets a result back.
User is logged in, and forwarded to a different view (login success message) by the controller.
Currently my views are static HTML (no PHP), so here is my question. What is the correct way to then pass the user a welcome message, e.g "Hello, Craig!"?
Is the view allowed PHP snippets, e.g
<?php echo $username; ?>
since the model is loaded before it in the controller file?
Thanks!
Edit: Is it better practice then to allow the view to access specific class methods e.g
<?php $user->getUsername(); ?>
as opposed to just variables?
Based on other answers, I have found a very useful article, which you may also be interested in.
http://www.nathandavison.com/posts/view/7/custom-php-mvc-tutorial-part-5-views
Here are few things you must consider:
You cannot do classical MVC in PHP. Instead we have MVC-inspired patterns
There exists 1:1 relation between view and controller instances, when implemented for web
Model in MVC is not a class. It is a layer, that contains a lot of different classes
View is not a dumb template, but an instance of class, which deals with presentation logic
View in Web-based MVC
As stated above, views in MVC and MVC-inspired patterns are responsible for presentation logic. That encompass things like showing error messages and pagination. To do this, each view can handle several templates.
View receives information from the model layer, and acts accordingly. The way how the information from model layer ends up in views is one of most significant differences in MVC-ish patterns:
classical MVC pattern
Structures from model layer send the information to view, when state of model has been altered. This is done via observer pattern.
Model2 MVC and HMVC patterns
View has direct access to the model layer and is able to request information from it. This is the closest to the original pattern.
MVVM and MVP patterns
View receives information through controller, which has in turn requested it from model layer. The further difference in patterns stems from what the do with data before passing it to view.
What you seem to have now is actually just a template. Similar to one, that is described in this article. You end up with a structure, that has no place to contain the presentation logic. In long-run this will cause the presentation logic to be pushed into controller.
So what about that "welcome" message ?
To show the welcome message, your view should request from model layer the name of current user. If the model layer returns some sort of error state, view pick the error message template and inserts into the layout.
In case if name of the user was retrieved from model layer without problems, view pick the template which would contain the greeting, sets the value in the template and renders it.
In what order parts should be loaded ?
The idea, that controller should initialize model and view, comes from very primitive interpretation of MVC for web. Pattern know as page controller, which tried to graft MVC directly on static web pages.
In my opinion, this should be the order:
Model
You initialize the structure, through which you will deal with model layer. It most likely would be some sort of service factory, which would let you build things like Authentication service for logins and Library service for handling documents. Things like that. I wrote a bit long'ish comment on model layer's structure earlier. You might find it useful.
View
You create a view instance based on information, that you collected from routing mechanism. If you are implementing Model2 or HMVC, then your view will require an instance of Service Factory in the constructor.
If you are implementing MVVM or MVP, then view's constructor has no special requirements.
Controller
This is the last structure, which you create, because controller is responsible for sending commands to both view and model layer, which then change then change the state of both. Therefore controller should expect to receive both view and service factory in the constructor.
After basic elements of MVC have been initialized, you call a method on the controller, and render current view.
Just keep in mind that this is very simplified description.
You can really put anything in a view that you'd like, but to better adhere to the MVC way of doing things you should restrict PHP in the view to simple echos or prints (possibly really small loops as well, although even those can be pre-calculated in the controller/model). Since that is the only way to get dynamic content, it would be a little silly to say that they are not allowed.
The idea of the view is to let it have a more HTML look-and-feel, so that front-end developers or people who don't know PHP can easily be able to work with the file without getting confused.
Update
To learn more about MVC in general, you can see any of these (there's a ton of tutorials out there):
http://blog.iandavis.com/2008/12/09/what-are-the-benefits-of-mvc/
http://php-html.net/tutorials/model-view-controller-in-php/
http://www.tonymarston.net/php-mysql/model-view-controller.html
To see concrete examples of PHP using MVC, I suggest downloading some of the more prevelant frameworks (such as CodeIgniter, Symfony or Drupal) and just looking through the code. Try to figure out how it works and then recreate the functionality for a simple article-based system.
I'm new to the OOP paradigm (and AJAX/jQuery), but would like to create a basic site employing MVC architecture, in PHP, with AJAX functionality. I drew up a brief diagram of how I currently 'understand' the architecture.
Presumably when AJAX is used, that acts as the controller to interact with the model directly to retrieve whatever functionality is needed? The filenames I added are just to give you an idea of what I 'think' should be included. e.g. index.php would be a html/css template with includes to modules in the relevant places (whatever they may be) - news.php, navigation.php, etc. database.php/pager.php might house the classes and extended classes that I create for pagination, or connecting/querying the database I'm struggling to see what the controller component could be - it'd surely end up being a 'second back-end view' - calling the classes from the model to be sent to the view?
I've probably portayed my confusion well here - what should go in the view, controller and model... is AJAX functionality technically another controller? Any diagram similar to my one above would be extremely helpful.
OK so AJAX is a transport method and not a piece of application like a model or controller.
Your client will communicate through AJAX with one or more Controllers.
These Controllers use or invoke Models to handle different kind of tasks.
Then either the controller or the model responds to the request either with a message in a transport-friendly format (JSON, YAML, XML) or with a View (piece of HTML).
The controller handles requests, that means it receives the initial client-input. Depending on the situation this input has to be formatted, normalized, mutated or transformed somehow before being used in your application.
Then a controller uses or invokes a model; this means that it either deals with business logic itself (old style) and makes use of the model to access datasources or it hands the main workflow of your application completely over to the model (new style).
A model in first instance abstracts a persistent storage entity (like a database). In contemporary application design it also does the main business logic of your application.
There's one way to see this.
Ajax is the medium for sending data between MVC components like HTTP POST. In this respect it does not show up in the MVC pattern.
The actual display in JSON format can also be seen as a view if it's actually used to show data.
From this you should be able to come to your own conclusions.
You can use PHP's best MVC architecture called "YII".Get more info from here
http://www.yiiframework.com/
I'm thinking of re-working my MVC before I get to far along with it. At the moment it uses a sinle controller which takes the user input and determines the model. The model has maby differ methods which I call actions, because one is called automatically. The model loads its view file, which again holds many different methods. The model can set properties which can be used in the view. Then the controller calls th template classwhich parses the output for display.
Is this the bst way to do it?
Or should each different part (news, contact, about) have its own controller, which loads a specific model and view. Essentially, instead of grouping methods into a single file, it uses multipe files.
I'm kind of lost as to how I should do it.
Cheers
Start using a MVC that works and is well-known like in Symfony or Cake. From that you will decide:
what do to in your own, knowing the best practices;
to drop your own if you feel like you can save time by using theses.
If you are thinking of advancing your own MVC model, like #e-satis have said, you will need to experience what is happening in already developed systems. However, as based on my experience in designing MVC model and determining what is there in opensource community, I stick back to my own MVC for two good reasons. One reason is the flexibility of customization and the other is own MVC privacy.
I used the following approach for MVC design pattern.
A Router.php file identifying user-request urls. This router will be able to fetch controllers and include the file and call the controller default method.
The loaded controller is also able to load other controllers if required to function. This is done using a global method, where all controller Class will extend to a MainController Class which is able to call to other controllers.
I do use a global registry to set and get variables from one controller to the other.
The Models are used to get the Data from Table, and most of my Models will represent Database functions which includes CRUD (Create Read Update Delete). So that a controller can easily manipulate database table data using a model.
Naming conventions in all controller, models, and views is also important, if you want to system to be more intelligent to identify the required action knowing the file name.
I use the Views separately for each type of controller. And these views will be sent to a Master Template View file.
Same as models, the controller will be able to set Views to Master View.
There are other customizations which you can do, like applying security methods before calling a class, or after calling a class/controller/model/view etc.
This is done by the MainController, which it will always look into a folder with autoload class which states what files should be loaded before and after of different actions during the process of building the content and delivering the output.
MVC is not a small scale idea, but it is a design idea which can always be developed. There are so many PHP MVC open source frameworks to be found if you know how to search the major search engines like google.com
But I do advice you that, MVC is not a good solution if you are simply developing a small dynamic website, as it will consume more time in developing compared to developing small websites. MVC is ideal, if you have business logic and needs system automation in order to avoid most routine tasks of developing, and like that I would say MVC is most ideal for larger applications.
The model loads its view file
The Controller should act as a Mediator between the Model and the View.
The Model shouldn't be aware of the way the view renders it, and also the View shouldn't be aware of any kind of logic of the Model.
In theory, if your MVC is well structured, you should be able to represent the same Model with different types of Views (HTML, XML, JSON for example).
Build FrontController which parses request uri and decides which controller to load and which method to run. With .htaccess rewrite all request to index.php
//index.php
class FrontController{
function run(){
//parse request uri here /comment/new
//load controller comment
//run controllers method new and pass some request attributes
}
}
// ../controllers/comment.php
class Controller_Comment extends Controller{
function new($request){
//do stuff here
}
}