I've always used the model as something to more or less store and execute database queries. I have heard about the fat model, thin controller concept.
The way I setup my models right now causes a lot of junk in controllers for things like validating forms, formatting data. Does form validation, file uploading and data formatting belong in the controller or the model?
I realize this question is subjective, which should create some good discussion rather than a concrete answer.
Form Validation should definitely be part of the model. I generally represent each form as one model and pass it the sanitized post/get paramaters. The model can then take whatever action is necessary based on the input and use a property (optionally with a getter) to signal success or failure. In psuedo code you want it to look something like:
class Controller
{
function action()
{
$input = new Input();
$form = new FormModel($input);
if ($errors = $form->errors())
{
//load the appropriate view for the errors
}
else
{
//load the appropriate view for success with an optional redirect
}
}
You have two main roads to go. Thin controller/fat model or fat controller/thin model. Basicly is were you put most of the interaction. I prefer to keep at the model the major portion of the code. That way, the code is available in virtually every controller and/or lib. If the code remain at controller, it's hard (but not impossible) to use it in other controllers.
Things lije validations and other common tasks should be in a lib or helper. You can produce a set of "workers" (this is the name I give to them) to do the heavy lifting. Also, CI has a LOT of ready made libs and helpers both from the CI team and the community. Mess around the wiki to find the wealth of information available.
Hope this helps
Vx
The model is what interacts with the data (most often a database). Controllers use the models to access the data.
Related
In a MVC application it is easy to understand how the Controller extracts data from the request and updates the Model layer but I am a bit confused as to how a View is supposed to retrieve data from the Model layer when the View does not know about the request?
For example if I go to
http://www.site.com/product/view/428
I route the URL and I dispatch the request and I end up in the Controller. Nothing needs to be done in the Controller(I think?) and when it gets to my View I need the product ID but the View should not be extracting data from the Request so what do I do?
Thanks.
There are two approaches for handling this and both actually would indicate that controller in this case a significant role to play.
The fabled ways of ancients ..
The first option for resolving this issue would be adhering to classical MVC as close as possible. This kinda relates to what people mean, when they say 'you cannot do classical MVC for web'. In classical MVC the view observes model layer. And that part can actually be implemented.
If that's the approach you want to take, then you will have to learn about Observer (1), (2) pattern and how to use it in PHP (1), (2). Though there has been some push for moving away from Observer pattern.
Since I have not explored this approach in any meaningful way, I will not give any examples.
The puny trail from this decade ..
If you read Fowler's "GUI Architectures" article, you might notice the part which state that views and controllers form pairs. When applying the ideas of MVC to context of web, there are ways to benefit from it in the bootstrapping stage of application.
FYI : I'm not anymore so sure, that you can call this way "Model2 MVC". There are some significant inconsistencies. I'm gonna poke more at this nagging suspicion some more, when I'm bored.
Consider this fragment:
$router->route( $request );
$resource = $request->getParameter('controller');
$view = new {'Views\\'.$resource}($serviceFactory);
$controller = new {'Controller\\'$resource}($serviceFactory, $view);
$method = $request->getMethod(); //post, get & etc.
$command = $request->getParameter('action');
$controller->{$command.$method}($request);
$view->{$command}();
echo $view->render();
The controller fragment in your example URL would be "product" and action would contain "list". I left those names instead of resource/command pair to make it less confusing.
If you start out with a premise that views and controllers are paired to some extent (whether the pairing is cohesive or not is debatable), then you can express it by using same names. This also lets you move the initialization of view out of controller.
Another aspect which is encapsulated in the fragment above is the fact that, due to the request-response nature of web, every operation in controller will require an accompanying one in the view. And similarly to how you have actions in controllers, you can also opt to call specific, route-related methods in the view. That would remove some boilerplate conditionals from views and let you better organize the whole thing (this is kinda the "highly subjective bit").
So .. how do you turn /product/view/428 request in something visible on site?
As you probably know, the responsibility of controller is to alter the state of model layer, which in this case might code something like this:
public function getView( $request )
{
$warehouse = $this->serviceFactory->provide('warehouse');
$warehouse->chooseItem( $request->getParameter('id') );
}
The your view instance uses the primed service from model layer to acquire data:
public function view()
{
$warehouse = $this->serviceFactory->provide('warehouse');
..
..
// retrieve data about sales for product with ID: 428
$something = $warehouse->getSalesFigures();
..
}
The exact implementation of view will depend on how far off deepend you are willing to go. Two most reasonable options would be:
fetch data, inspect it and if necessary choose templates and dump data into them
use a set of presentation objects to work with model layer and based on the result bind those presentation objects to ant number of templates
my 2 cents
In MVC, A controller "controls" the flow of information between the model, where the information is "stored," and the view, where it is displayed. Therefore, the controller handles all the changes of information and interaction with the models and then sends the necessary information to a view that then displays whatever information was requested/changed/etc.
MVC is all about the separation of responsibilities.
Models are responsible for storing and modeling the application's data.
Views are responsible for displaying information to the user.
Controllers actually have multiple responsibilities:
Deciding when to Create new instances of a Model.
Deciding which instances of Models to Read and passing them to the appropriate View.
Deciding which data in a Model instance needs to be Updated based on data passed back from a View.
Deciding when to Delete no longer needed instances of a Model.
In other words, Controllers sit between the Models and Views and do all the business logic for an application, including figuring out which CRUD operations need to happen... although the actual CRUD operations are usually part of the Model itself.
A better name for MVC would probably be MCV to stress how the Controller sits between the Model and View.
Is this a good practice to handle normal and ajax calls with one controller:
<?php
class SomeController extends Controller {
function index() {
if(!$this->input->is_ajax_request()) {
// load model
// create form
// pass data to view
// ...
} else {
// validate input
// load model
// write data to database
// return with some json string
}
}
}
What are the advantages and disadvantages?
Short answer: it depends.
Only real difference between XHR (what marketing people call "AJAX") and ordinary browser request is that XHR expects a different form of response.
In the MVC-inspired patterns for web the part that is responsible for generating response are the view instances. The view should recognize, which kind of response it has to produce, and act accordingly. Controllers role in this scenario would only be to change the state of current view.
Alternatively, you can, at the bootstrap stage, detect the Accept HTTP header, and based on that initialize a different view instance.
With "fully implement view" I mean an instance, which contains UI logic in the MVC triad and can decide which for to respond. This response can be HTML document, composed from multiple templates, a JSON/XML file or just a simple HTTP header.
Pros: proper separation of concerns, easier to maintain
Cons: have to implement full MVC
.. but most of people do not use full MVC implementations.
If you are one of people, who, instead of MVC-inspired patters, uses Rails-like variation about page controller pattern, then you will be force to create a separate controller for handling XHR.
In this scenario the is no real view. It is replace by dumb template, while UI logic has been merged in the page controller. In this situation the only pragmatic option is to create a separate controller to deal with XHR.
Pros: simpler to implement in small projects
Cons: possible code repetition, harder to maintain
Even if it's an AJAX request, you still have to validate the input. It's not you sending your app the input (via AJAX), it's the browser, which you cannot trust.
As a general design principle, avoid special cases (here: ajax vs. non-ajax). In general, you want to treat all cases equally, so you end up with an orthogonal approach.
And as you can see
class SomeController extends Controller {
function index() {
if(!$this->input->is_ajax_request()) {
// validate input <-- XXX here we need to validate it too
// load model
// create form
// pass data to view
// ...
} else {
// validate input
// load model
// write data to database
// return with some json string
}
}
}
this leads to duplicate code (hard to maintain and keep in sync).
Your code, orthogonal approach:
class SomeController extends Controller {
function index() {
// load model (takes care of his own validation, the self-containment principle of OOP)
// coordinate same business logic done by different models
// return models/data to the view, the framework will decide whether it uses the html or the json view file
}
}
Instead, the model (it could be the same model class, or a Form model like there is in Zend Framework, or a hydrating approach like there is in ZF2 could do most of the jobs (together with a Table Gateway, DAO (like in Doctrine 2), or similar classes for models), and you could create two sepparate views for HTML and JSON.
In Zend Framework 2 for instance, the right view is chosen transparently for you, so there really wouldn't be any if/else regarding "is this AJAX or not?".
You should try out a modern PHP framework (5.3+) to get a feel of how to approach the design of your app in PHP.
I think this is developer choice, consider this:
I think this is developer choice, consider this. Development of a client Mobile site I have seen. They have a store for web and a model store:
/store/model/order.php
/store/controller/order.php
/store/view/order.php
Rather than
/store/model/order_mobile.php
/store/controller/order_mobile.php
/store/view/order_mobile.php
The management is a nightmare. Seperate images, css, multiple coding duplicates for mobile clients. The solution for them now is to convert the entire site into a responsive design
/new-dev-store-responsive/model/order.php
/new-dev-store-responsive/controller/order.php
/new-dev-store-responsive/view/order.php
Same code but cleaner. And I would have AJAX calls inside my templates with the PHP structure on some code and others not. Again it can be difficult to manage. It would better to handle using JSON or external static files - so the PHP is driven using GET, POST etc.. and if they have JavaScript the AJAX works WITH the PHP.. PHP code should stay PHP IMO..
/new-dev-store-responsive/model/order.php
/new-dev-store-responsive/controller/order.php
/new-dev-store-responsive/view/order.php
//new-dev-store-responsive-cdn.com/assets/js/order.js
//new-dev-store-responsive-cdn.com/assets/css/order.css
//new-dev-store-responsive-cdn.com/assets/imgs/order/checkout.jpg
There are a few advantages and disadvantages in your method.
For Posting public data there is no problem.
For Getting public data I usually prefer to do it in separate controller, many time I don't even put ajax check, because my data is public and I want it to go as far as it can..
For Posting/Getting private data I prefer not to use this two sides method because its better to have good and clean (secured) Code...
How ever.. all depends on your choice. Everything is possible! And there aren't constants which is right and which is not..
As I understand it, MVP is a derivative of MVC where the Model and the View are loosely or completely decoupled, and the Presenter replaces the Controller and acts as the bridge between the View and the Model. This pattern seems more appropriate than traditional MVC in web applications (whether or not that is true is not the subject of this question, so please refrain from going down that direction).
My problem is in implementing the various MVP pieces in PHP, using a passive view. Here is my current flow of things:
The PHP script sets up an autoloader and a router. To me, this means whatever view was in existence send an event of some kind to the server.
The router then determines which presenter should be used based on the request.
Here be dragons. The Presenter acts as the bridge between the View and the Model and should take a View and a Model as dependencies so it can easily be tested. That means I need to know what model and view I should be using before the presenter is created.
The presenter seems to be the class that knows what Model and what View it needs, so how can I move that logic out of the presenter? I understand that the generic pattern to use is a factory, I just can't seem to understand how to implement it in this case.
Perhaps I am doing this all wrong. Maybe I've been coding for too long of a stretch and am experiencing mind warp. Regardless of why I can't seem to understand how to solve this problem, I'll accept any guidance.
Not 100% sure I know what you're asking. You are right that you load the appropriate controller based on the request. That controller is typically associated with a model and a view.
Let's say you have a URL that looks like: http://www.example.com/test/view/1
It would be fairly standard to load the Test controller, call the method view pass it the argument 1. So let's assume you have:
TestController.php
TestModel.php
test.php (view)
When the TestController loads it includes the model, TestModel, where your "data stuff" goes (I think you understand that). So for this example, let's say view wants to load the last 5 posts from the user with id 1. So in TestController.php:
function view($arg)
{
$userID = $arg;
$posts = $this->model->loadPosts($userID);
$this->render('test', $posts); // outputs the HTML in test.php
}
And in test.php, you can loop through $posts and output it however you choose.
It seems like you already know how this stuff works though, which is why I am confused as to what you're asking. Does this clear up anything?
I find it useful to think of Web Apps in terms of states and state transitions. the application is in a particular state, it's "at" a View, some HTML was with the aid of the associated Presenter from data in the Model and rendered to the browser . The user takes an action and this is going to move our app to a new state. So we are moving from one View/Presenter pair to another. In my mind the Model is a longer lived, evolving thing, I don't see us getting a new Model for each transition.
So you have PresenterA, responsible for responding to events in ViewA.
PresenterA receives some event, performs some work that may result in Model changes, and then decides which View to go to, say ViewB. ViewB can create its Presenter. As per the Wikipedia example (not PHP I realize, but the principle is clear):
public class DomainView: IDomainView
{
private IDomainPresenter domainPresenter;
public DomainView() // Constructor
{
this.domainPresenter = new ConcreteDomainPresenter(this);
}
}
In effect the Presenter is the creator of the next View/Presenter pair. If you have more complex logic replace the explicit constructor
new ConcreteDomainPresenter(this);
with a factory, working with View and Model information.
Given the URL http://www.example.com/products.php
products.php contains:
<?php
include ('model.inc');
$controller = new Controller;
class Controller
function __construct()
{
$model = new Model;
$this->model->model_methods();
include ('view.inc');
}
}
?>
model.inc contains:
<?php
class Model {
// methods that return data
}
?>
view.inc contains:
<html>
<head>
</head>
<body>
<!-- html plus php output -->
</body>
</html>
So products.php creates the controller. The controller creates the model, figures out what to do and manipulates data only through the model's methods, and finally turns things over to the view. The only php in the view is to output data or to loop through an array to output data.
I've been playing around with a few lightweight php frameworks that implement MVC, but so much of the magic gets done backstage that I don't know if I finally get it or not. :)
Have a look at this MVC article on Coding Horror.
If you think about what a model represents - a "model" of the data, or a subset of the data - and about what the view represents - a particular "representation" of the data - then it's easy to understand that these two entities require something to route the information between them. Hence, the controller. The flow should be M -> C -> V
A good test if you "understand" MVC (and thus, if your application is MVC) is "Can I skin my application?" If you can think of an easy way to apply different skins and styles to your data seamlessly, then you have succeeded in separating the model from the view, and your controller is effective at what it does.
Although I don't know how it's actually implemented, I'd argue that StackExchange is a great example of the MVC idea. There are multiple sites dealing with multiple topics, but they all have very similar kinds of "models" - very similar data. The presentations - the views - are free to change as they please, and the controller is there doing all the logical heavy-lifting. This may be kind of a contrived example, but I think it works conceptually, if not technically.
Personally, I think your Controller is responsible for too much. Instantiating the Model and View inside the Controller "feels" wrong. The Controller should only be responsible for getting data from Model and giving it to View. Right now the Controller is responsible for creating the Model AND it is effectively acting as the View by including the HTML.
The important part here is that each object has, ideally, a singular responsibility.
Model = the data holding your app (this is really a layer instead of an object)
View = the final output sent to the user
Controller = give stuff to View from Model
I recommend you create some kind of "front controller" type object that handles the appropriate instantiation of objects and is the one responsible for setting up all the different pieces.
Ah, ok, but how does the controller "give" the data to the view?
Well, this is really gonna be dependent upon the precise architecture your particular implementation uses. MVC goes far beyond a simple design pattern and can be interpreted in a variety of ways. I prefer something that looks like...
class Controller {
protected $viewData = array();
public function index() {
$data = $this->Model->getData();
$this->giveToView('data', $data);
}
public function getViewData() {
return $this->viewData;
}
protected function giveToView($key, $value) {
$this->viewData[$key] = $value;
}
}
So, the Controller is still getting the data from Model but now instead of including a view file we just store the data and let a different class take care of actually rendering the output.
class View {
protected $viewData;
public function setViewData(array $data) {
$this->viewData = $data;
}
public function renderViewFile($filePath) {
// from example the variable $data is now available in this scope
// to include the $filePath
extract($this->viewData);
include $filePath;
}
}
Obviously this is a simplified example but the basic premise stays the same.
The idea of the MVC is to separate your application logic (business logic, business tier, middle layer or middle tier), input (url, post data, get data) and output (UI - the html in your case).
It is an determined as architectural pattern (software architecture). It is not matter of code but of ideologic for building applicaions.
Read here: MVC in Wikipedia
I would prefer CodeIgniter - a very static collection of functions, some named Model other Controller and there are Views plus a lot of utilities, allowing you to concentrate on the application logic and the layout, without loosing coding freedom in PHP (seems you use PHP). Unless you find out that it's not fitting, but that can happen with any framework.
Yes. This is more or less MVC. The basic gist of MVC is as follows:
Controllers tie your models and views together and normally take care of passing model data to the view.
Models handle your business logic.
Views handle presentation and presentation related logic.
I'd definitely take time to learn PHP MVC framework such as Kohana, Lithium, Symfony, or Cake as they all provide a ton of utilities to make your life easier. They can also handle automatic routing wich makes your URLs cleaner, and helps abstract URLs from their direct connections to controllers.
Kohana: http://kohanaframework.org/
CodeIgniter: http://codeigniter.com
Lithium: http://li3.me/
Symfony: http://www.symfony-project.org/
Cake: http://cakephp.org/
Not quite yet!
The /products.php portion is generally abstracted. The file name is matched in a router during execution, which matches it to a corresponding controller. In this case, you could have a Products controller by name, but you could match (via routing) a things.php request to the Products controller.
There's generally some more execution/initialization "magic", which calls the pertinent model/view based on the request - for example, it would take /products.php, change to Product, and look for a model, controller, and view named Product.inc
Yes, that is the essential basis of the MVC pattern. The controller can be thought of as the brain which figures out what action to take. Depending on that action, it may communicate with models to get the necessary data to render the view. It then makes the necessary data available to the view and renders the HTML for the browser.
MVC at it's most basic definition requires that you split the navigation logic, the data logic and the presentation logic into 3 parts. There is no special structure to observe as long as you have the parts split so that you can easily interchange and isolate your code.
Obviously, there are many more topics to cover if you want to be an hardcore MVC layout.
For example
Splitting your application into folders called controllers, views and models
Creating a good data layer to simplify your models as much as possible
Integrating a helper/widget logic so you can reuse visual components
Integrating a routing engine with mod_rewrite to create clean urls
Those are just a few of the items you should cover to get a real good MVC layout. But then again... MVC is a design pattern, it's a way of doing things without being something totally concrete or concise.
I want to add a user in users table via link like '/index/adduser/id/7' .
Question
Should I validate user input inside 'adduserAction' function inside controller or somewhere inside model file? I've put files containing database related functions inside 'models' directory. Suppose a user is added to a table via 'id'. This id is sent via 'get'. And finally its added to table by 'AddUser' function (inside model file). Then I should validate this 'id' inside 'adduserAction' or 'AddUser'.? Scalability-wise, would it be better to do it inside 'AddUser'?
There's a popular believe / paradigm that states:
Thin controllers, fat models.
What this means, is that your controller should only be responsible for doing the bare minimum to make sure actions change the state of models and serve the right view in return. With this in mind, the validation should occur in your models. But... hold on for a minute. Models aren't necceseraly 1 tiered layers.
I believe among .NET programmers the following setup (or something similar) is a pretty common practice (if the scale of the project validates it):
Controller
-> ServiceLayer
-> Repository
-> DataObject
And I'm starting too like this setup more and more. Moreover, I believe this setup is very doable in a Zend Framework environment too.
The term Model is somewhat of a vague term. In the above you could consider the three last layers as your Model layer. What the three layers represent is the following:
ServiceLayer:
Responsible for business logic. In other words: retrieving Dataobjects (Models) from the repository, tying Models together, AND validating Models before storing them, mailing a user, etc..
Repository:
Some type of persistence mechanism (like a Database), that serves DataObjects to the service layer, and stores DataObjects back in the persistence mechanism (after the service layer validated them)
DataObject:
You might consider this the actual Models. Preferably DataObjects have common interfaces (independant of the Repository that is), so that Repositories are interchangeable. In other words, when the repository changes from a database to an XML file from some webservice, the DataObject still has the same interface the service layer and ultimately the view can work with.
Hope this makes sense. This is basically my understanding of a more layered MVC setup right now. If anybody feels I have things mixed up please feel free to correct me.
Please keep in mind though, that not all projects dignify such a layered setup. In smaller projects you could perhaps do with just a 1 layered Model layer. In that case, validating should still be the Model's responsiblity. The controller should be thin (just for tying Model state and Views together through actions).
I would say put the validation in your model. You can then keep your validation rules in a central location. How should your controller know the exact length of a valid user name? That is model territory. Your controller can ask the model if a user name length is correct or not sure, but the rule itself needs to be in your model. In my controller I would do something like this:
$model = new Model;
$model->loadFromArray(something to get post);
if (!$model->isValid()) { forward back to form }
$model->save();
the ideal solution is to use validation inside your forms - i.e. appending it to your zend_form_elements - see http://framework.zend.com/manual/en/zend.form.elements.html
I'd do it in the Controller, not the Model. IMHO that's the better place because then the sanitized data is secure to use in the controller already. That's a good thing for comparing things, etc., even before the data is actually saved.
I know it's already answered, but I remember the "younger me" combing the web for some choice resources on sites like this and would like to share my research and what I do here. I do the following:
I use forms to do input validation
and filtering Do my validation inside
models
I have a validation method
which proxies the form validation
method.
This validation method can called upon
internally by model methods or externally
by the controller or view.
Here's a quick example:
//UserModel
class Default_Model_User
{
protected $_form;
public function getForm()
{
if(!isset($this->_form)) {
$this->_form = new Default_Model_Form_User();
}
}
public function validate($data)
{
if($result = $this->getForm()->isValid($data)) {
// if you have custom validation conditions outside of the form, then you
// can do the validation here also.
if($data['controller_entered'] == 'some value') {
$result = false;
}
}
return $result;
}
public function saveUser($data)
{
if($result = $this->validate($data)) {
// do something.
}
return $result;
}
}
If you haven't read it already, be sure to check out the Surviving The Deepend book freely available on the following URL:
http://www.survivethedeepend.com/zendframeworkbook/en/1.0
This chapter is specific to your dilema:
http://www.survivethedeepend.com/zendframeworkbook/en/1.0/implementing.the.domain.model.entries.and.authors#id1491270
You will no doubt run into other issues as you progress through... It may help to check out the comments on my blog post regarding the model layer where I cover this issue: http://www.rvdavid.net/my-zend-framework-model-layer-part-service-part-orm/
Hope this helps someone out.