What could I do to improve my MVC? - php

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
}
}

Related

Laravel controllers for complex pages

I have started a new laravel website project and I have hit a road block in my understanding of MVC. I need to refactor to continue but I don't know the best way.
Currently I have web pages that display the results of a single bit of logic. I.e. A page listing all users, a page listing the details of just one user etc etc - all handled by a userController. This applies to other pages being handled by other controllers.
I have created models directly relating to the tables in my database, and controllers in relation on the models. I moved the business logic from the controllers to services. The controllers use the services to perform the business logic and with the data returned, pass that data to the views.
This nicely groups similar functionality together and works fine.
userTable -> userModel -> userController -> userService
clientTable -> clientModel -> clientController -> clientService
...
In my routes, I have pages which do related functionality use the same respective controller, but individual methods depending on what the page does
/listallusers -> userController#list -> userList.blade.php
/listallclients -> clientContoller#list -> clientList.blade.php
/listdetailofoneclient -> clientContoller#details -> clientDetails.blade.php
This is ok when dealing with pages that do that functionality and (apart from using services) seems to be what is hinted at in the laravel docs.
However, I'm starting to get confused about controllers when dealing with pages that either don't really use functionality from any of the services or pages that heavily require functionality from multiple services (and the data needs complex manipulation like formatting or such).
A basic index page.
What controller would handle this? The index might link to routes that are handled by existing controllers but it probably won't need to display much functionality apart from that. That means the controller won't need to pass much complex -if any- data to the view. You could stick the logic to return the view in the route file but that is pretty tightly coupled.
A page that shows complex client and user data
You need to pass client data and user data to the view from the controller. But from what controller? This is the part that is really holding me back.
Because I have a limited number of pages but lots of logic displaying on each page, I was thinking of making a page controller (or something) which would handle the routing. Although I have looked, I have not seen any real mention of this idea anywhere which makes me think I am either reinventing the wheel or have failed to grasp some basic concept in laravel / MVC.
Would the page controller in this case handle all the routing? Would it handle only the pages with 'overlapping' existing controller functionality and the pages that don't fall into the existing controllers? Is a page controller even a good idea?
Some more points that have made me question MVC from this issue
Do controllers need an equivalent model?
Can controllers 'control' other controllers in order to separate logic?
I'll take a shot at a couple of these questions.
Having a PageController or HomeController is very acceptable. Controllers don't have to be linked to a specific model, for instance an AuthController would handle logic for logging in and out but isn't tied to a model, or PasswordController which handles setting/resetting passwords, or a PaymentController that handles billing routes. A controller is just a way to organize logic for related routes in one file. Static basic pages are related routes so a PageController makes sense to me.
Are users tied to a specific client? If so you can arrange your controllers in a nested way so you have a ClientController and a UserController and your routes look something like this:
/clients/{client}/users //list all users for this client
For heavy data formatting it's probably best to use a service provider and use dependency injection to inject it into controllers where you need to use it. This allows you to detach your data manipulation from your controller so you could change it out if needed. Say you are using a software to make charts, and you want to change it out later - you want that formatting logic to be removed from your controller.
I hope I helped in some way... sort of a train of thought here!

Basic MVC (PHP) Structure

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.

Way to bypass the controller in CodeIgniter?

I've been using the CodeIgniter framework for PHP and am enjoying it, but I notice that it seems to require a controller for every view. I'm wondering if there is a way to call a specific model from the view itself, rather than route through a controller. I understand that use of a controller is best practice in most cases, especially where the data from the model needs to be modified in some way, but I have cases where I just need to do a strict data pull to the view (which is loaded via ajax), and setting up a controller for that seems superfluous.
Any thoughts? Thanks in advance!
You're fundamentally misunderstanding MVC, at least as implemented in CI.
All URLs on your site (at least those that utilize the CI framework) are mapped to functions (methods) within controllers.
http://myCIsite.com/controller/method[/var1][/var2]...
It doesn't matter whether the URL is accessed via regular HTTP or via AJAX. This is always a one to one mapping. Because of this, you should think of the controller/method combination as the "web page". Do not think of the view as the web page.
Models and views are subordinate to controllers. The controller delegates specific responsibilities to them - database interaction for models, and page output to views.
Because models and views only serve to perform delegated responsibilities, their use is not required in any given controller/method. Help pages, for example, generally have no need to interact with a database, so there is no model utilized by the controller/method combination that serves a given help page. Likewise, form handlers frequently redirect to another page upon completion of processing. As such, there is no view corresponding to the form handler (but there is (likely) a view called from the controller/method in the redirected to page).
Furthermore, models and views do not necessarily correspond on a one to one basis with individual controllers/methods. Any given model can be loaded and used from within several controllers. Similarly, a controller could have a single monolithic view that is used by all methods, or each method could be assigned its own view. (Or, as I just said, a given controller/method could utilize no view at all.)
Finally, CI does not enforce strict MVC separation. You can interact with the database and echo HTML all from within the controller and CI will not complain. Nevertheless, this separation and delegation of responsibility is followed because logically separating the responsibilities makes the code easier to read and helps you follow the DRY principle in your coding.
The fundamental Understanding is that the "web page" corresponds to the controller/method. The view and model, when used, handle delegated responsibilities for the controller/method.
I'm wondering if there is a way to
call a specific model from the view
itself, rather than route through a
controller.
That's not possible as of what I know, the main abstract class of the CI controller imposes restriction to use a controller otherwise you will get a fatal error.
And actually what you say will break the best practice of MVC design pattern. You got to go to model through a controller not view.
I'm a bit confused as to exactly what you're trying to achieve. The controller's value, aside from just being a clean way to handle incoming requests, is to manage the interaction between the models and the views and to determine which views to load. It's also entirely reasonable to load model data directly from your views, but how did you get to your view in the first place?
I guess I'm just having a hard time seeing the context here..
To run a query via Ajax you still need to provide a URL / path in the javascript call. You can not get around the fact that a controller function has to "catch" this call; you can not map a url directly to a model. All you need is 3-4 lines of code in your controller.
Via URI routing you can map a URL to a different controller, so you don't "require a controller for every view". I always create a controller called "ajax" to handle those requests.
A basic ajax call with jquery can be something like this
$('#prod_img').load( "http://domain.com/ajax/get_img", {'color': 'blue', 'url_title': 'bla' } )
You can echo stuff in your controller, so rather than trying to bypass the controller you should be looking into how to do away with the views. This will actually be easy, you can load the db class in the controller just as you can in a model.
But if you really don't want to use MVC perhaps Codeigniter is not the framework for you.
You should read more into the principles of MVC.
Views are strictly for presentation of data, the model shouldn't communicate with views directly.
But still if that's what you want then just pass $this->db from the controller to the view and use it in the view.
Then again, this is NOT a good practice.

models using controllers?

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.

General on mvc... should controller pass data to view or view should grab it directly from model?

I’m trying to learn and fully understand mvc pattern and learn php at the same time. I decided to built basic mvc framework that I could use on various projects later on. Having read lots of posts in here regarding mvc and coupling between models/views/controllers I’m a bit lost.. At the moment my understanding is that in web application controllers deal with coming request from browser and, if necessary, calls methods on model classes telling models to change its state. Then controller instantiate appropriate view class that will be responsible for displaying interface.
Here's the bit I don’t understand...
Now should controller pass appropriate model object to view and view should pull out all the data from model when needed?
Or controller should grab data from model and pass it to view, possibly wrapping it all into single wrapper object that view will access and grab data from there?
Or view should simply instantiate appropriate model when needed and pull out data directly from model object?
From what I read here
http://www.phpwact.org/pattern/model_view_controller
I’d lean towards the 3rd option where controller doesn’t pass anything to view and view instantiates model it needs. This is because:
view and controller should have same access to model
controller shouldn’t act simply as mediator in between view and model.
Is there really one correct way to do it or it rather depends on project? Also what approach would you recommend to someone who has decent understanding of OOP but is relatively new to php and not too clear on mvc architecture. Or maybe I should go with whatever seems right to me and learn from my mistakes (would like to avoid this one though ;)?
Now, please let me know if my question is not clear will try to better explain then.. Also I read lots of posts on stackoverflow and numerous articles on different sites, but still would appreciate help so thanks in advance for all answers.
Personally, I've always been a proponent of #2. The view shouldn't care about the model. The view shouldn't have any processing at all for that matter. It should do what it's supposed to do, format data.
The basic flow of control should be thus: The controller recieves a request from a browser. It processes the request, decides what data is needed, and retrieves it from the model/s. It then passes the data into the view which format the data and displays it.
As an extension, user input is processed inside the controller, and saved into a model if needed, then feedback is fed into a view, etc. The key point to take away is that processing happens inside the controller.
Personally, I've always been a proponent of #3. The view shouldn't care about the controller. The view shouldn't have any dependency on the controller for that matter. It should do what it's supposed to do, show a view of the model.
The basic flow of control should be thus: The controller receives a request from a browser. It makes any updates to the model, that is relevant, and then selects a view. The control is then passed to the view, which gets data from the model and renders it.
As an extension, user input can be consider part of the model, and both the controller and the view may read from it. The key point to take away is that Controller and View should have no dependency on each other. That's why the pattern is called MVC.
Now, personally, I find MVC a bit too tedious, and so I usually conflate Controller and View more than this. But then that isn't really MVC.
Web MVC and Desktop MVC are two very different beasts.
In Web MVC, a link in a View calls a method on a Controller, which updates a Model, and then redirects to an appropiate View, which opens up a Model and shows what it needs.
In a Desktop MVC, option 3 is wrong because both the view and the model should use the same reference. In Web, there's no choice.
Option number 2 is not MVC. It's MVP, wherein the Presenter is a mediator.
A Controller has Write-Access to a Model; a View has only Read access.
This is a very interesting question.
From my experience most implementations in php assign a model variable to the view:
$this->view->my_property = $modelObj->property
This is common practice.
The common reasoning for this is that if you send the object then you can call methods that modify the object from the view.
//in the controller file
$this->view->myObject = $modelObj;
//in the view file, you could call an object modifying method
$this->myObject->delete();
And modifying the model from the view is considered bad practice. Some people thing that they don't want their designers being able to call model modifying methods from the view.
That being said. I don't agree with the common practice and tend to assign the whole object to the view and display it from there. And just discipline my self to not make operations there.
And a third option is to assign the whole object to the view. but some how in the objects disable methods when they are called from the view.
I think this is just a generic argue about what is better "push" or "pull" model. There is no "absolutely" best solution.
I had a very similar question earlier. I find helpful to think of it as follows:
MVC
Model -- Data store, alerts Views of changes
View -- Displays model, provides hooks for user interaction
Controller -- Handles user input
You would use MVC more often in non-web apps, where lots of classes are interacting with eachother simultaneous.
In a web application MVC means MVT (Model-View-Template)
Model -- Strictly a data store, typically an ORM solution
View -- Handles web requests, provides for user input/output
Template -- Actually displays content (HTML, Javascript, etc.)
So in a web application the presentation is handled in the Template, the logic behind the application is handled in the View (or classes called by the view), and the model is responsible for holding data.
The reason why so many developers today can't get the knock of MVC is because the abbreviation of MVC was incorrectly stated from day one when it arrived into software development, but the concept is correct back then and also today. Since I am from the old school, let me explain it for you; when you are creating an object you first create a Model so the customer can View it, once it is approved you will have full Control on how the object is going to be made. That's how it is to this day in product manufacturing.
In today’s web application development such term should be VCM. Why! You View what's on the web browser, and then you click a button for action, that is known as the Controller. The controller alerts the Model, which is the instruction or logic to produce a result (that is your script). The result is then sent back to the user for viewing. In software engineering, you can refer to it as CMV; because the user won't able to view anything until the apps is compiled and installed. So we will need a Controlling device (PC); the OS as the Model and a monitor to View the results. If you can understand those concepts, MVC should start to look much more appetizing. I hope this concept will help someone to understand MVC.
I tend toward having the controller act as an intermediary between the model and the view, but generally this is literally a single line of code that connects the three together. If your model, view, and controller are properly decoupled it should make very little difference which you use.

Categories