I have some (basic perhaps) knowledge of the Model-View-Controller pattern and I want to create a site using this. But I find it a bit confusing how to actually implement this. I get stuck in the details.
Say that I have a site where each user keeps some todo lists. How would you approach this?
What classes would you create? Which class would output the HTML, which class would server as the controller and how would it communicate with the view to produce the output? etc.
Sorry if it seems silly and I guess it must be somewhat easy but I am stuck.
For the record:
It is not as hard to do a MVC in PHP, its more related with to be disciplined rather to be a difficulty task.
a) Model(s) (optional, you can use an array in PHP)
<?php
class MyModel() {
}
?>
b) Route (index.php?)
<?php
include "...";
// here we collects all the information, such post,get and path values
$action=...;
$param=....;
switch($controller) {
case "my": // www.myweb.com/my/action
include "controller\MyController.php"; // open the right controller.
break;
}
?>
c) Controller
<?php
include "model\MyModel.php";
switch($action) {
case "add":
// here live the logic, information, call for services and such.
$model=....;
// and finally...
include "view\MyView.php";
break;
}
?>
d) View
<html>
<body>
<?=$model->field;?>
</body>
<html>
As a note:
a) The view should be clean as possible. Think that the view could be created by a web designer that doesn't care about php.
b) The view is always the last step of the process. The view web always returns nothing.
It is very possible to do this without an existing framework, and just create your own. Its not a very difficult task anyway.
Not being application-specific, your MVC framework would have to do the following:
Redirect all trafic to a central page, so that every request gets
handled correctly.
Extract the controller and action from the request url. (for example, a request to http://yoursite.com/Task/Add, you have to translate that to the Add method on the TaskController)
Load the controller class (in our example TaskController). Perhaps using Autoload.
Call the Add method on the Controller
Show the result
There are multiple ways to implement views, you could emulate ASPMVC and have each Controller's action return an ActionResult, which has one method Execute. Then an overload of that, ViewResult would take care of loading the correct view and including it with the proper ModelData.
Here's the precise answer to your question from RASMUS LERDORF himself.
Read through.
Read the following intro to Symphony network:
http://symfony.com/doc/current/book/from_flat_php_to_symfony2.html
Although your question is a little too broad, I think I can provide some help.
The number one question I had when starting out with frameworks was: Which framework, if any, should I use? In your case, I would not try to build a MVC website without a premade framework. Most of the architecture you will end up writing has already been done dozens of times over.
Things like DB abstraction, login systems, etc. are boring to write. Might as well use a framework that already has these things.
I would highly suggest this book: http://www.amazon.com/Building-Applications-Symfony-CakePHP-Framework/dp/0470887346/ref=sr_1_2?ie=UTF8&qid=1315227178&sr=8-2. It will walk you through building a simple MVC website using three different PHP MVC frameworks. By the end of the book, you will have enough experience with each framework so that you can choose which one you like best.
Alternatively, if you'd like to write your own framework so that you can learn how it's done, I'd recommend TJHeuvel's answer. Another option is to read the source code of an existing framework so you can see how others have implemented it.
The comment by Kheldar makes perfect sense. The tutorial actually covers making a micro framework using the MVC pattern.
Although you'd need to add to it - in terms of adding custom routes and some sort of routing engine but apart from that it is a very good baby step into developing your own MVC framework..
Related
** simplified question **
I am learning oop patterns and I am looking to build my own simple mvc framework. I would like this to have a front controller but I am finding it difficult to find any credible information for implementing a front controller with MVC.
In particular I am confused about whether the front controller should initiate the entire triad or whether the front controller simply calls the controller and the other parts do the rest.
I have noticed classes like route, router and bootstrap and I am wondering what these particular classes do and whether they are dependent on the front controller itself.
Actually that's not a question, you're just trying to get suggestions on how to proceed while building your own MVC framework.
So I'll try to provide an answer / consideration as generic as your question.
1) "I'm learning OOP Patterns": patterns are as much powerful as dangerous in the wrong hands. What I'm trying to say is that you should start building your fw without trying to use every patterns you come across the net just because it is used or talked about by the big ones. You can refactor you code later providing each step an higher level of abstraction: this will naturally involve using the patterns you'll be reading about and a better understanding of them.
2) "confused about whether the front controller should initiate the entire triad": that's up to which level of coupling you're aiming to have in your mvc.
You can have your Front Controller handling everything like:
bootstrap: load config and instantiate database connection and so on
request: get the needed data describing what was asked
route: handle the request
response: return what was asked
But what if the configuration is needed somewhere else? Maybe in a CLI running script? You'll be naturally detaching the bootstrap component from the router to use it anywhere else is needed. And the same is for the other components.
3) "classes like route, router and bootstrap".
Imagine to have your big class handling everything. How will you be testing your methods? Will you manually call the script with different inputs? Will every testing method have to check for the input, the routing and the output at once?
Providing an abstraction level upon every component involved in your Front Controller encapsulating it in a proper class/object/module, will give you far better testing capabilities.
I'm talking because I've been down that road before creating exactly what you're talking about: https://github.com/OverKiller/PHP-Router
But I had to face hard testing capabilities and deep coupling.
I'll be rewriting it soon, abstracting the request, the route and the response component.
But I had my experience and I'm proud of it!
You should do the same.
What I'm trying to say is: do not try to build the next Ultimate SymZendCakeIgniter PHP Framework all at once.
Take your time, take your time to read and take your time to learn.
And for god sake: *even before reading anything about design patterns get a nice book about T-E-S-T-I-N-G
I hope I was useful.
i have a project i took over. it is an app that has been build over many years with PHP and mysql.
It currently has a sort of good folder structure but the code itself is very poor written.
There is php, sql statements and html code in almost every file.
There is javascript code generated using php echo for not reason and so on.
I will like to use for further development either CakePHP or CodeIgniter, even if that means that for the new features some code will be written that already exists (eg.: maybe utility functions) in the old code.
is it possible to integrate one of these frameworks into an existing app?
which one is easier?
do you have any links on how to do it?
thanks.
I have very little experience with CakePHP so my answer is going to be about CodeIgniter. I played with CakePHP for about a day and that was almost two years ago. In my opinion it will probably be easier to integrate with CodeIgniter although someone more experienced with CakePHP might prove me wrong.
Here is the approach I would take. I have never done this, but it seems like a logical way to approach the problem. I suppose this approach would also work with CakePHP.
First, start with a fresh CodeIgniter install using the latest version.
Next, create controllers and actions (controller methods) that mirror the current structure of the application. For example, if you had a page with the URL http://example.com/users/view you would create a Users controller with a view() method.
Next, create view files for each of the current files of the application and load them via the appropriate controller methods. The goal here is to get the application working using CodeIgniter's routing system although at this point you won't be utilizing any models, libraries, or helpers.
Once you have the application sitting on top of CodeIgniter, start refactoring it to fit into the MVC pattern. Pull out application logic (queries, form handling, etc...) from the view files and place them into the controllers. Keep all presentation logic and HTML in the views.
Next, refactor the controllers. This is where it gets tricky because controller code can be placed into models, libraries, or other controller methods. A good starting point would be to take all of the queries and put them into appropriate models. Compare your controllers and see if there is any code duplication. That is a good sign that you should remove it from the controller and place it elsewhere. Unfortunately I can't really tell you where because it differs in each situation.
Continue refactoring your application until you have it in a workable state that you are pleased with...
Hopefully this helps. I certainly missed some critical steps such as setting up and configuring CodeIgniter but if you're serious about doing this I would highly recommend reading through the CodeIgniter User Guide to get a good idea about how it works. You should also get familiar with MVC (model-view-controller) if you aren't already.
There's not really a one size fits all solution here but hopefully I've given you some ideas or at least a starting point to jump off of. If you have any questions or are a little confused drop a comment below and I'll get back to you.
In my opinion, it's easier just to write your controllers in CodeIgniter (I've never used CakePHP) and models, than you just copy paste with some adjustments the views.
My problem is actually not the ajax loading itself, more the capability to load it without javascript. I mean, I cope easily when I code my whole project just based on ajax-availability OR just without the use of ajax.
//EDIT: Although Arend already had a more or less valid answer, at the same time 'there is no direct answer to this question'. However, I'd like to see some other approaches of developers for scenarios like mine though! Even just a few links can help!
Basically I just get frustrated, coding everything twice on the same page to make sure that both users without and with Javascript enabled have the same experience. It's annoying and I was always wondering how others solve this problem.
When I update for example two divs with dependency on the same variables, it gets messy. Here's an example:
non-js-version
require 'classobject.class.php';
$another_var = 'something';
$class = new classobject($_POST['variable']); // just an example to show that this is dynamic - I'm aware of injection!
$function = $class->returnsth(); // returns 1
if(isset($_POST)) {
echo '<div id="one">Module 1 says:'; $require 'module_one.php'; echo '</div>';
echo '<br /><br />';
echo '<div id="two">Module 2 says:'; $require 'module_two.php'; echo '</div>';
}
Now in module_two.php and module_two.php I have code that executes differently depending on the return variable of $function.
Like:
if($function >= 1 && another_var != 'something') {
// do stuff
}
else {
// do other stuff
}
Now as this works easily with a reload, when I want to load the two modules on keyUp/enter/submit or whatever, I have basically a few problems:
I have to send the $_POST variables manually to the modules to use them
I have to re-execute the class & it's methods and make a link (require_once) to them in each of the module-files.
As $another_var is not existent in the modules, I'd have to send this variable to each modules, too (with post for example) and then before it can be used, I'd have to 'change' it like $another_var = $_POST['another_var'];
I find this mildly annoying and I wonder how you guys do that. I hope my way of coding is not too silly, but I can't think of another way. It's probably hard to relate to my very basic example, but to bring a whole project with the code would be too much. To sum it up, I'm looking for a better way to code and clean this mess up - there must be a way! I thought about sessions, but for compatability I don't want to rely on them either (if someone doesn't allow cookies).
In case you can't relate to what I'm trying to accomplish with that way of having my code assembled, I'll explain a scenario I'm facing quite a lot (not important if you already understand my misery):
Basically I have my index.php page where everything gets executed, with the html body and css styling and so on. This page expects some variables, that get set from the page that requires the index (like $another_var in my example).
Now other variables can get set too (from a form for example). Depending on that different classes and methods load new variables (arrays) that get used in while-loops in my modules to echo everything out.
Hope that's not too abstract. Think of a booking system where some variables are set from the page you are coming from (the event you want to book) and then a few more things get set by the user (a timespan, some preferences,...). In the end it's supposed to show results from the database all the way to the end-result - you can say the user narrows the results from step to step.
There is no direct answer to your question, but there is some food for thought.
Seperation of concerns
You can think about if you can perhaps seperate your buisness logic and layout logic. Often the use of a template engine can help greatly with that. I've had positive experiences with for example Twig or Smarty (was some time ago, not sure how they measure up right now). It requires you to write your code in a (less linear) way, but more logical.
A typical example of an OOP like seperation of concerns might be something like this:
$this->setParam('Myparam','myvalue');
if ($this->isAjax())
{
$this->setTemplate('ajax.php');
$this->setLayout(false);
} else {
$this->setTemplate('normal.php');
$this->setLayout('Mylayout');
}
return $this->render();
It is an imaginative situation, which can be found in many MVC like applications and frameworks. The main idea is that you should have the possibility to seperate your layout from your data. I would suggest looking at some of the modern frameworks for inspiration (like symfony, codeigniter, zend framework).
Glossary / Often applied concepts in a decoupled PHP application
Here is a quick list of concepts that can be used.
Example mvc in php: http://www.phpro.org/tutorials/Model-View-Controller-MVC.html
Note: I don't really like the implementation. I much more prefer the existing frameworks. I do like the explanation in total of this tutorial. E.g. for me this link is for learning, not for implementing.
Silex
For a simple decoupled php micro-framework I would really recommend silex, by the makes of symfony2. It's easy to implement, and to learn, but contains mainy of the concepts described here; and uses all the php 5.3+ goodies such as namespacing and closures.
see: http://silex.sensiolabs.org/
Frontcontroller Pattern
Only have one, and one only point of entry for your code. I usually only have one, and one only point in your application. Usually a frontcontroller 'dispatches' the request to the rest of the application
http://en.wikipedia.org/wiki/Front_Controller_pattern
Routing
A routing system is often used in combination with the frontcontroller pattern. It basically describes which URL is connected to which module / controller. This allows you to change the way people access your app without changing the urls.
See: https://stackoverflow.com/questions/115629/simplest-php-routing-framework
Controller
A controller is the place where buisness logic is applied. Getting the data from the database, checking privileges, setting the template, setting the layout, etc. (although this is also moved outside the controller if it becomes too big of a seperate concern).
Model
The model basically is the layer in which use manage your database. This can be a simple class where you move all your mysql_* functions, or it can be a full-featured ORM. The main philosphy is that all the logic related to fetching and placing information in the database is seperated.
One step up: ORM
An often used method in applications are Object Relational Models, these 'map' SQL records to PHP objects. Doctrine and Propel are two of these well worked out libraries. I heavily rely on these systems in my development. In this sense, the doctrine or propel part will represent the model layer.
Doctrine: http://www.doctrine-project.org/
Propel: http://www.propelorm.org/
Other ORMS: Good PHP ORM Library?
PHP ORMs: Doctrine vs. Propel
View:
The view usually consists of a templating engine. Some use plain PHP as a template, others, such as symfony create a seperate scope in which variables are placed. There are many discussions and opinions about what is best, one is right here on stackoverflow:
Why should I use templating system in PHP?
PHP vs template engine
Ones I like:
- Twig: http://twig.sensiolabs.org/
- sfTemplate: http://components.symfony-project.org/templating/
- Smarty: http://components.symfony-project.org/templating/
Decoupling mechanisms:
Event based systems
Using events in your can help to seperate the code. For example if you want to send an email after a record has been saved, events are a good solution to do that; in general the model should not have to know about email. Thus events are a way to connect them: you can let your -email-send-class listen to certain records in order for them to send the right email. (Perhaps you'd rather want your e-mails send from your controller, this is probably a matter of taste).
Dependency injection
When using OOP code in PHP many relied on having singleton classes running around (configuration, etc). From an OOP point of view, this can be considered bad, because it's hard to test it, and it's not considered very elegant to have dependencies running around like that. Dependency Injection is a pattern that came form Java and is now used in the newer frameworks to get around this. It might be a bit difficult to wrap your head around, but you will see it coming back in several new frameworks.
Dependency injection in php: Dependency Injection in PHP 5.3
Frameworks:
A lot of these methods are difficult, or a lot of work to implement yourself. Many will reside to a framework for this. You may or may not need a framework. You may, or may not want to you a framework, it's your choice. But it's still useful to learn how the frameworks do it, and not try to reinvent the wheel yourself.
The no-framework php frameworks: https://stackoverflow.com/questions/694929/whats-your-no-framework-php-framework
Good habits: https://stackoverflow.com/questions/694246/how-is-php-done-the-right-way
Frameworks worth looking at (imho): CodeIgniter, Kahona, CakePHP, Symfony (1.4/2.0), Silex, Zend Franework, Yii. There are many many more, each with their dedicated fans and haters.
I wrote something like this with PHP. I already had abstracted the rendering of every page such that I define a $content variable and then require('layout.php'). The $content variable is just a big HTML string.
I wrote a PHP function to determine if request was AJAX or not.
The non-AJAX responses render the layout with $content in the middle, b/t header and footer layout content.
AJAX requests basically get this: json_encode(Array("content"=>$content)). And I use jQuery to get the HTML out of the JSON response and modify the DOM. Using json_encode() will handle escaping the string for javascript.
In the end, I effectively have AJAXified every page w/o over-engineering a complex solution.
Any browser that supports AJAX can also open a link in a new tab/window to simulate the non-AJAX request. (Or bookmark/share a link, too.)
Greetings all!
Looking for some help with MVC in a PHP context. Currently I am building a small, lightweight MVC framework to help expedite application development at work. It's a long hard separation eliminating inline code - at least with numerous projects looming overhead and the temptation to utilize it ever-present.
I understand most of the basic requirements of MVC, and I've already begun porting some of my existing classes that are in Singleton pattern over as utilities in my new framework (these are mostly basic 'handlers' to perform site services - a class for file uploads, authorization, wrapped PDO database queries, error printing etc.)
What I can't seem to grasp moving forward after reading much documentation is the best approach to instantiating views. In my old, inefficient design I would switch off a $_GET variable to switch ouput from within the home view. Just going off intuition, this seems like an extremely bad way of getting the job done.
I've looking into CodeIgniter, and it would seem that there are predefined functions for loading views within that framework. What is the best approach to such an application design? Would it be a class based 'link factory' that utilizes the same variables to fetch content, select the proper view file, and place it in the page flow? Also, how could the new view be included between the header and footer includes in the root index without using switches? This is the only thing really confusing me - I really hope I have worded myself clearly enough.
Thanks all as ever!
I highly recommend "PHP Objects, Patterns, and Practice" by Matt Zandstra. A good bit of the book deals with creating MVC frameworks and would be very, very helpful to you.
It covers these patterns (which you can also research elsewhere):
Front Controller
Application Controller
Page Controller
Template View
View Helper
While I'd suggest going with an established, flexible framework (like Zend), to answer your question, here are the steps involved as I see them (understand I stopped trying to write this kind of stuff a while ago, this is based on my understanding of the existing frameworks I've used).
Some kind of router parses the request and translates to a controller object with an action (or takes the default) and optional parameters. The router then calls the controller object's function matching the action.
The controller object (usually extended from a generic controller object) process the request and determines what data to pass to the view, as well as what view to use. Most frameworks setup a default view based on the action, but ultimately it's up to the controller to decided what view to use.
The view takes the data and displays it.
That is my very simplified take on the process.
In the last couple of websites I made, I implemented a kind of MVC-style controller, I think.
I used mod_rewrite to send everything through index.php, so the url became a querystring.
It worked, but I'm wondering if it's a bit hacky, or just the accepted way of doing things. Is there a better way? I don't want a framework, I want to learn to do it myself.
Try my smallest framework in the world.
<?php
$g=$_GET;$c=#$g['c']?$g['c']:'Home';
if(!#include"c/$c.php")die('fail');
$m=method_exists($c,$m=#$g['m'])?$m:'index';
$o=new$c();$o->$m($g);
That goes in index.php and your controlls are Blog.php in ./c/Blog.php.
class Blog {
function index()
{
echo "Hello world";
}
function otherpage()
{
echo "ZOMG!";
}
Made mainly as a joke, as I wanted to make a framework that could fit in a tweet, but the basic logic is there ;-)
Passing everything through a single point of entry, e.g. index.php is not MVC, it is the FrontController Pattern. This goes well with MVC though. See my related answer here.
Apart from that, why not check out some of the frameworks around to learn how they do it. Doesn't mean you have to use them, just look at their code and adapt for your own framework.
That's the way I accomplished it. I then created a dispatch table that new, based on URL, which controller to instantiate and which dispatch to run.
How about learning to do it yourself, but still use a framework ? Either way, take a look at an open source framework like Symfony or CMS apps like Wordpress, Jommla! etc, and you will find that they all use mod_rewrite to set things off.
Most PHP frameworks make use of mod_rewrite do accomplish the same objective, and it's the only way to suppress index.php and make the urls more friendly, in a segmented way.
I'd say you're in the right path.
That method you used is called FrontController Pattern, and it's used by those frameworks as well, to go along with the MVC pattern.
If you care for a suggestion, I'd recommend you to make every request pass through each page controller, extending a base controller, since every site has some base data structures that you will probably need to use in every page, such as templates and session control.