What do I want to do?
I am trying to create a little application in PHP to manage user requests and registrations. I am not using any MVC framework, but I want to make it following the MVC because I want to scale it and reuse the code of some components.
My Question:
If the Controller does not manage the View, how can it access the mail's final presentation (content+format) before sending it?
In which guidelines I want to base it?
I have read some articles about MVC in web applications, and I have intention to meet the following specifications:
The Model:
In its simplest form the model stores data which is to be accessed by the view and written to by the controller. The model is the most complex of all the parts of the system and will contain all the logic which is specific to the application and where domain entities that relate to real world concepts (such as "a user" or "an order") are stored. It is the part of the application which takes data (from any source) and processes it. The model also handles all data access and storage. It has no knowledge of any controllers or views which may use it.
The View:
The view contains all the display logic. In PHP it will be the part of the application which generates the HTML. It has direct access to the Model and can query the model to get its data. The View can create callbacks to its controller (for example a clicking a button in the view would trigger an action in the controller). In MVC the view queries the model to request its own data.
The Controller:
The controller takes user input and updates the model where required. Where there is no user interaction (e.g. where a static data set is displayed and will be the same every time), no controller should be necessary. It is important to note that the controller is not a mediator or gateway between the view and the model. The view gets its own data from its model. The controller accesses the model but does not contain any display logic itself. All the controller does is respond to user input.
It's important to note that the controller is not in charge of instantiating the model or the view. Each controller is linked to a single instance of a view and a single instance of a model.
The above specification could be summarized with the following diagram
Trying to do it with Mailing Case
So I assume that the Controller is the one that is going to send the email(s) and the View is the one that is going to prepare the email(s) presentation.
The more detailed version of the previous diagram, adapted to the mailing case (please, notice the discontinuous arrow with an interrogation, as it is where my question lies):
Is there anyway to keep the following general program flow?:
//initiate the triad
$model = new Model();
$controller = new Controller($model);
$view = new View($model);
$controller->{$UserRequest};
echo $view->output();
I do not find any solution to this. Is there any way to proceed that I cannot find?
Thank you guys for your help...
Mail is generally considered as a part of "helper class".
Indeed, mail should be sent through the controller class, but defined in helpers for more clarity.
You can use phpMailer for example (really easy to use in MVC).
Related
I am creating an MVC inspired PHP framework, mainly for learning purposes.
I basically have the framework created and am building an app on it and improving the framework as i go along.
I am still confused/not sure about certain aspects of this sort of architecture, and at the moment i am questioning my implementation of the View part.
How i have set up my framework:
Its a very simple set up, for example: you go to the url /post/post_id, this will load index.php which will instantiate the router. The router will then check the url and instantiate the correct controller and method based on the url. In this case it would be PostController, and the method would be a default method that would use the post_id to get the posts data from the relevant model. Next the controller would set up a "data" variable that will hold the data to pass on to the View, and this is where i am confused - should it send to its own View object (a view class file dedicated to the PostController), or to a generally used View class that is used by all controllers to load an html file?
At the moment my controller is sending data to the View class, this data includes what template file should be included/shown, and the actual data for the page (what we got from the Model through the controller).
My question is this:
Should this type of system have one View object that renders all of the views (html files) based on what data is given to the "render" method, or, should each controller that eventually sends data to the View have its own View object/class?
Meaning, should PostController send a request to the general view class, the same one that is used by all controllers to renders pages, or should the PostController send to a dedicated View Class (call it PostView if it makes it clearer), and this class will then render the specific html file?
Basically if it should be one View class for all controllers that will render what ever html file the controller tells it to, or if there should be many View classes, one for each page load.
NOTE:
I know a lot of questions have already been asked about MVC in PHP, but i could not find an answer to my question in any of the answers.
A bit about MVC:
In the original MVC pattern (presented by Trygve Reenskaug in 1979), the controller updates the model, the model notifies the view about the changes, and the view pulls its data from it. Though the pattern was thought for desktop applications - each M-V-C "triad" beeing related to a single control in a window (a button, a textbox, a checkbox, etc). So, each control on the screen had an MVC "attached" to it.
Since, in web applications, the model-to-view notification step is not (or can not be) present, the original pattern can not be applied as is to them.
But a most similar approach can still be relatively easily implemented: the controller updates the model, the view pulls data from it (irrespective of the controller). I think it's called "Web MVC Model 2".
There is a multitude of web MVC variations. You are using one in which the controller takes the role of an intermediary between the model and the view.
So the controller is the only one component communicating with the model.
The view's responsibility:
The responsibility of the view component is the presentation logic - which should not be assumed by the controller at all. Beside loading and rendering template files, this kind of logic involves the preparation of the data fetched from the model for displaying purposes. The result of the preparation should, preferably, be a list of values of primitive types (strings, booleans, integers, arrays, etc) which can be easily "injected" into the template files during the load-and-render process.
Examples of presentation logic:
Example #1: If you would fetch the value 123.45 (from the column amount of a table revenues) from the model, the presentation logic would consist of formatting it to the string 123.45 USD, in order to be displayed in a template file.
Example #2: Formatting a fetched date value of 28/05/2019 to 2019-05-28 by using a code snippet like this:
$fetchedDateFromModel = '28/05/2019';
$time = strtotime($fetchedDateFromModel);
$formattedDate = date('Y-m-d', $time);
The value of $formattedDate would then be "injected" into a template file.
Example #3: Setting a boolean value based on some model data, in order to be used in a template file for deciding if a button ("Get Bonus") should be active or not.
$paidAmount = 512.79; /* model data */
$isActiveGetBonusButton = false;
if ($paidAmount > 500) {
$isActiveGetBonusButton = true;
}
The answer (in respect of your chosen MVC approach):
By using a View instance in all controllers, you would be forced to perform specific presentation logic in each controller - before passing its result (e.g. the list of the prepared values) to the used View instance, in order to further just be "injected" in a specific template file.
Whereas, if you are implementing a dedicated view class (like PostView - which, preferably, inherit a base class View containing the render() method) for a controller class (like PostController) - so a 1:1 relationship, but see it as a loose one! - you can pass the data fetched from the model, in an unprepared form, from the controller to the view. The view class would then correctly take the responsibility of preparing the data for displaying prior to actually load and render a specific template file. E.g. of performing the whole specific presentation logic.
Note: In "Web MVC Model 2" - where, ideally, the controller has no knowledge of the view component - the above argument is more obvious:
the PostController just updates the model (when an update step is required);
the PostView fetches data from model, prepares it for display, and displays it (by loading & rendering a template file like posts.html.twig, for example). In other words, the view component performs the whole presentation logic by itself.
The best way, IMO, is to have this View or Template class do all the work related to views with just one simple method: render(string $templateName, array $context = []).
This allows for easy extension or creation of adapters. You should make your controllers use this method. If you use a DI Container in your framework, you could do a TemplatingAwareInterface and implement that with a trait that allows setter injection. That will inject the templating service on fetching from the service container. That way, you can use $this->templating->render() in your controller, without having to either make it global, nor constructing the templating service inside the controller, nor injecting the container into the controller.
Having one view class for each type of controller is cumbersome, harder to maintain and I don't really see a reason for it.
I am learning PHP programming and came across MVC (Model View and Controller). Can anyone explain more about Model and Controller?
In the following stack overflow question What is the best definition of MVC?, there was an answer that Model is responsible for databases. But isn't it controller which process and use database?
No, they're not the same. The Model contains everything your app can "do".
Classes which describe your data structures? Part of the Model.
Function/method/service for creating new users? Part of the Model.
Sending email notification? Part of the Model.
Complex database queries? Part of the Model.
Everything else? Part of the Model.
What the Controller is is an "interface between your Model and the outside world." The Controller takes input from outside world, like an HTTP request, or a command line input, or an event on an event bus, and decides based on that input what action should be triggered in the Model and perhaps with what kind of View to respond. You may have different Controllers for different scenarios (web server, command line interface, cron job) which adapt those different scenarios to actions in the underlying Model.
for MVC in PHP, i've found Codeigniter to be very useful! Altough it differs a little from MVC in other Languages...
here from theyr definition:
The Model represents your data structures. Typically your model classes will contain functions that help you retrieve, insert, and update information in your database.
The View is the information that is being presented to a user. A View will normally be a web page, but in CodeIgniter, a view can also be a page fragment like a header or footer. It can also be an RSS page, or any other type of “page”.
The Controller serves as an intermediary between the Model, the View, and any other resources needed to process the HTTP request and generate a web page.
https://codeigniter.com/user_guide/overview/mvc.html
No, controller and model is not the same in MVC architecture. The model is being used to keep track of all the business data. The controller tells it what to do, and the model knows how to do it.
Controllers orchestrate the application. Controllers receive events from the
outside world (normally, user input), interact with the model, and display an
appropriate view to the user.
The model is responsible for maintaining the state of the application. A model is more than data; it enforces all the business rules that apply to
that data.
To learn how the concepts fit together, see the
following figure:
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 have seen all types of tutorials:
View running controller, controller passing model to the view, controller setting setter of view.
An example: MVC for a reading of a news.
The controller loads the Model. If the result of the model is 'false' I can call another method from another model containing different block.
The View class must be relevant to, View_found View_not_found?
if (model-> news === true) {
$ comment = model-> comment ()
}
Would this code snippet be the responsibility of the controller or is it a rule that such logic should belong to business model?
in my experience, i tend to program the model and view as "blind". the model and view only receives parameters needed and then spits out what is needed. they should do minimal to no logic at all.
for the model it performs minor checks, like parameter type and validity and returns either a result or false. the controller does not know how the data is stored, where, why etc.
for the view, it should receive a string preferably through only one entry point, a function which will do the escape and echo. other than that, the controller should never echo to a page.
everything else is for the controller to digest like validation, calling what's needed, determine what is what. the controller sees everything:
//get from model, pass parameter - that's it
if (model-> news ('all')) {
//manipulate data for result
//get appropriate view
view->parse(html); //pass html to view, that's it
} else {
//manipulate data for no result
//get appropriate view
view->parse(html); //pass html to view, that's it
}
If you want to find model News comment, you need to create Comment model and get it from your dataProvider and render to view.
Here is a part of controller action code :-). All logic must be in controller. Views is only render content parts.
UPDATED I recommend using here dataProvider. Model method (getter) can return DP object for model.
It depends which framework you're using.
Like said Rasmus Lerdorf
MVC is the current buzz in web application architectures. It comes from4event-driven desktop application design and doesn't fit into web application5design very well. But luckily nobody really knows what MVC means, so we can6call our presentation layer separation mechanism MVC and move on.
As a matter of fact, in web application, it is common to use "action oriented MVC" instead of "event MVC".
You've got a controller that knows his model, and the view to apply.
To display news, You must have a News class which is your model, a NewsProvider which deals with your database.
Your controller compute the datas given by the database and the user and call the proper view.
The best practice is to keep business logic in Models
see below links for reference
http://www.yiiframework.com/doc/guide/1.1/en/basics.best-practices
ASP.NET MVC - Should business logic exist in controllers?
http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx
If I get this right than function of the Controller is processing POST data and technically making changes to the state of the application (e.g. DB) via Model.
As far as I understand, View also gets data from the Model.
So this is how I understand the workflow:
Client request --> App Front Controller --> (if method = POST --> Controller) --> View --> back to Client
Here Model is used by Controller to read and write data and by View to read data.
So controller is not used every time the page is loaded, in fact, only when app data is added/updated. Most of the times Controller is bypassed.
Thus, how come almost every resource about MVC is talking about Controller sending data to views?
I am trying to write an app using MVC-like pattern. So in my app views always get data for the page from the Model. When Model is updated, I add specific model update time to Memcache. At runtime each View looks up last update time(s) of related model(s) and last time cache for this view was generated. If model was updated before cache was saved, view reads cache, otherwise re-renders based on updated model.
The controller is responsible for presenting views based on the data that is requested. It's there so neither the model nor the view need to know about the request. Yes, the view gets data from the model, but not always directly; the controller may have to make some decisions as well depending on the request.
It's something like having waiters in a restaurant so they can take orders from and serve dishes to customers. It's not the chefs who bring out the meals after preparing them; it's the waiters. It's not the customers who go to the kitchen asking for meals; it's the waiters who take their orders then let the chefs know what to prepare for whom. In the same way, the controller is there to handle client requests, whatever their nature may be. It's a very rough comparison though, but I hope you get the picture.
Unless I misinterpreted your question: The problem is with the view accessing the model directly. That's not supposed to happen as it defeats the reason for the MVC pattern. The view shouldn't know anything about the model itself, so the model can be exchanged for something else - the controller should supply the data (at most times it a flattened or projected way) to the view.
If I did: The controller is never bypassed. Just because it doesn't do anything with the data, doesn't mean it isn't needed - it provides a layer of abstraction between model and view. The point is to be able to exchange the model without having to adjust the view.
The controller is never bypassed as it is required to instruct which views are shown and what data (if any) is used in those views. Each get or post request to an MVC site uses the controller to control what is shown or collected to/from the client.
At its core MVC is used to separate concerns. The model works with the data, the views handle presentation and the controller provides the logic between the two.
If you are a person that learn faster by getter hands dirty with codes or looking to something visual , like me ....
I will suggest you to follow the tutorial in railsforzombies.org . It pretty much explain all the basic using rails , including MVC. In the tutorial , It mention that if you put all those logic in view , It will be messy. The code will sux a little bit because the guys that want to use your code will be confused with codes. By putting all the logic in controller and output it in view. It will be very clear for the person that look into your codes.
Usually Controller uses Model, and passes proccessed data to View. View shouldn't see Model. Main goal is - to keep View separately from Model!
MVC for dummies: why does controller
have to send anything to views?
This is the main point of MVC: to create loose coupling by separating and distinguishing the application's concerns. You have the View, Model, and Controller doing specific tasks.
Why the need for separation because it's hard to debug and fix a one gigantic godzilla app. Imagine fixing a car made from stone. There are no bolts. Everything is chiseled from a big rock. How hard is fixing that if you just want to change the wheels. You will need to chisel out the rock itself.
The main job of the controller is to handle requests and display the appropriate view. That it's job. It's like asking why does the mailman need to send the mail. Because that's his job.