I'm developing a web application using a very simple (maybe not really MVC-compliant) MVC framework, coded by myself while developing the application to keep the code clean.
My application, though, has many AJAX components and now I'm stuck trying to integrate them within the general MVC structure. How should they be integrated?
I have something like this in my Javascript files:
$('#pageList').load(BASE_SITE_URL + 'ajax/pageList.php');
and pageList.php used to have a structure like the following one:
<?php
require '../includes/config.inc.php';
require BASE_PATH . 'includes/init.inc.php';
// a whole load of Controller logic here and then...
echo "<table>";
//display some user data
echo "</table>";
I'm really confused about this, any advice is appreciated
Few pointers - your website should be functional without javascript. For example, if you have pagination with page urls like /list/?page=1 ... /list/?page=n then you should make sure all of your pages are clickable without actually needing javascript.
Javascript should really be an extension to your website. In the above example, you can come back and use js to replace the functionality of all the pagination with a simple ajax behavior. What you would probably want to do is use jquery.load to do something like:
$("div.content").load("/list/?page=2 div.content > *");
Note the selector after the load. This is very important because I haven't actually created any new HTML pages to make my website AJAX enabled. Instead I use what already is available to the browser as a simple URL and load it using ajax.
Of course, there are times that you need AJAX only content where won't really exist on a URL. In a situation like this I recommend creating a controller for all your ajax stuff and then rendered each path with a view.
I hope this helps.
Here's what I do in my apps:
check for a $_SERVER variable called XMLHttpRequest. If it's set, it's an ajax request and then you can do some logic so that your code doesn't load the views (templates and what not) and outputs a different header() (if any)..
I usually have a js script related to each view called update.js. It's role is to define how the user interacts with the view and create the HTTPREQUEST.
Then I have a file called controller.js that receives it, decides what to do with this request
and asks the model for the response.
Finally the update.js which belongs to the view updates the view with the new information received from the model.
My app directory structure is like this:
model/
model.class.php
business.php
controller/
controller.php
controller.js
view/
view.php
update.js
index.php
I organize the files by it's role rather than the type. I think this is the best approach to the MVC pattern with AJAX. Remember that the aim of this pattern is to keep encapsulation and scalability and this is the best way to do it for me.
Related
i know that this question already has been asked. But i still dont understand it.
Right now im trying to understand how to make use of the MVC Modell.
But i dont get how to integrate everything and right now I am hesitating to use a framework before i really get it.
What I try to achieve:
I want to have a header, a footer and a menu which remain the same all the time.
Like this:
HEADER
MENU
{CONTENT}
FOOTER
So my thinking is:
My Controller gets some Information, lets say its a User-ID.
Controller calls a method from the Model:
Get all DATA from USER with ID: 1
Then the controller passes the DATA into a view, lets say a list.
So where to go from here?
Should the controller pass this view into another view?
Like:
$site = new View(); <br>
$site->wholeSite($content);
and then site is something like:
HEADER
MENU
{$content}
FOOTER
Please excuse my simple approach, im just trying to get the basic idea behind it and i already read the first 20 pages of googling it.
Just cant get my head around it.....
It would be really nice if you would explain it for an Beginner :)
Thanks in advance!
you can call multiple views from the control like:
$this->load->view('header',$data);
$this->load->view('menu',$data);
$this->load->view('content',$data);
$this->load->view('footer',$data);
If you have a nested div then you can use regular include function like from a particular view file.
include('footer.php');
According to the path of the view file. The data also gets transferred from parent view to the included file.
Generally MVC apps have a universal layout view which contains the header, footer and menus. Sometimes data required for that is handled outside the controller, in say your init script or bootstrap.
An MVC purist might pass all data the layout requires from the controller, but that can be repetitive, although setting the data in an abstract controller construct might alleviate that.
On the question of views and sub-views there are generally two solutions:
A.) You have one principle view which all required data is passed to. In that view sub-views (partials) are called, and data is passed down into them.
B.) You instantiate all your views in the controller, passing all the data they need directly into the view, you would then pass views as parameters into other views.
Both methods have their pros and cons. I find the first option leads to less Fat Controllers, so I usually go with that.
I'd recommend you learn an existing MVC framework ( CodeIgniter, now defunct is basic enough to make it a good entry point), as that will show you how things are done.
I am migrating an old project to Zend Framework. I have a drop down list that changes filter context. In the old project the onClick event of the <select> list ran a function that made a jQuery ajax call to a php script that essentially updated the $_SESSION variable and then the JavaScript reloaded the page when the response came back. I have a couple of questions:
Is this an okay practice?
Should I send the request to a Controller instead of a servlet? One of the issues with this is that the drop down list is built in a view helper and is available across all Controllers, but I understand I could put the necessary code in and have them all inherit it.
If I DO go the stand-alone servlet type route, where do I put the php file in the hierarchy? I'm assuming the public folder- so pardon me if it is a dumb question.
I'm not familiar with Zend_Session, are there any gotchas to watch out for?
--EDIT--
After some initial code testing I have run into an issue with my servlet php file (let's call it registrar.php) is not able to get the Zend_Session_Namespace from the Zend_Registry when it is standalone (I'm not sure if I'm not doing it right, but since it's not being sent through index.php it makes sense to me that it can't access the registry). Instead of registrar.php I'm going to create a RegistrarController
I have created a RegistrarController, disabled the standard layout and view and put my logic in there
I thought of having an AJAX module service layer, with controllers and actions that interact with my model. Easy, but not very extensible and would violate DRY. If I change the logistics of some process I'll have to edit the AJAX controllers and the normal controllers.
So ideally I would load the exact same actions for both javascript and non-javascript users. I have thought about maybe checking for $_POST['ajax'], if it is set I would load a different (json'y) view for the data. Was wondering how/a good way to do this (front controller plugin I imagine?) or if someone can point me to an UP TO DATE tutorial that describes a really good way for building a larger ajax application.
You can actually use the request object to determine if a request has happened through ajax, e.g.:
// from your controller
if($this->getRequest()->isXmlHttpRequest()) {
// an ajax request, do something special (e.g. render partial view)
} else {
// render entire view
}
That's basically testing for the x-requested-with header (which is not always present, depending on JS library, etc). See (under the heading of 'detecting ajax requests'):
http://framework.zend.com/manual/en/zend.controller.request.html
You can check for XmlHttpRequest headers. Not all Javascript libraries do this, though, and even the ones that do don't necessarily do it in all browsers.
There's also AjaxContext, which basically checks the "context" request variable similar to your idea of $_POST['ajax'].
What I actually ended up doing was similar to your original suggestion. I created an AJAX module. In order to prevent tons of controller code duplication, I created a service layer that handles all the operations on models, so my controllers are really only responsible for transforming input requests and display.
All the examples I've seen of what and how MVC SHOULD be have used classes as the models, classes as the controller, and HTML templates as the view. And all of them consisted of one index.php script and different requests in the url to run the entire site.
So they've all been something like...
MODEL
class User{
function getUser($userID){
$sql = mysql_query('SELECT name......');
// more code.....
return $array
}
}
VIEW
<h2><?php echo $user['name']; ?></h2>
CONTROLLER
class Controller{
$userModel = new User;
$userInfo = $userModel->getUser($id);
$template = new Template('usertemplate.tpl');
$template->setVariables($userInfo);
$template->display();
}
I understand why the model is made of classes that simply get and save data (even though I assume classes arent always necessary and functions could be used). I understand why the template consists of mainly HTML. But I dont understand why the controller is a class. I would assume the controller to be a procedural script (like userprofile.php which gets the users data from the model and sends it to the template for displaying).
Also, I was wondering why every tutorial I've read dealt with mod rewriting, and using a single page with requests in the url like "index.php?user=1", or index.php?news=3 to run the entire site. Whats wrong with having separate pages like user_profile.php?id=1, or news.php?id=3...
Can somebody please help me with a quick "tutorial" and an explanation along the way. Like...how would a registration form be implemented using MVC, what would go where and why? thankyou
PS. what other kind of design patterns are there
The big "win" of the controller in PHP's version of MVC is you get away from having a separate PHP page for each and every URL that your application responds to.
When you have a new single page being created for each URL, you're expecting your developers (or yourself) to pull in the needed libraries and initialize the template/layout engine in the same way. Even when you're a single developer, the temptation to break from the "standard" way of doing things usually ends up being too strong, which means each URL/PHP-page ends up being its own mini-application instead of each URL/PHP-page being part of the same application. When you have multiple developers this is guarantied to happen.
The end results is pages and components that don't play nice with each other and are hard to debug (with everything hanging out in the global namespace), giving an inconsistent experience for both the users and the developers who have to work on the project.
MVC frameworks also make it easier to give your site friendly URLs. There's usually enough going on in the routing system that you don't need to resort to a huge number of query string variables. Readable URLs are a plus, for SEO and for savvy users.
Finally, although this is pie in the sky with most shops, when you have a controller the methods on the controller become easily unit testable. While you can technically wrap a test harness around a non-MVC site, it's always a pain in the ass, and never works like you'd like it to.
using a single page with requests in
the url like "index.php?user=1", or
index.php?news=3 to run the entire
site. Whats wrong with having separate
pages like user_profile.php?id=1, or
news.php?id=3...
Using a single entry point makes some things easier, I suppose :
You don't have to duplicate any portion of code in user_profile.php and news.php
If you want to set up any kind of filter (like PHPIDS for security, or ACL, for instance), you only have one file to modify, and it's done for the whole application.
PS. what other kind of design patterns
are there
There are a lot of design patterns ; you can find a list on the Design pattern (computer science) article on wikipedia, for instance -- with links to the page of each one of them, for more details.
There's nothing wrong with having separate scripts for each action, and in fact you CAN create a MVC architecture this way, without using a class for the controller. I'm working on an MVC framework at the moment that supports both styles.
The important thing is really to keep separation of different concerns. Database logic goes in your models, Layout logic goes in templates, and everything else in the controller.
So for a really simple example you could have a script "register.php" with the following code
$signup_options = SignupOptions::getSignupOptions(); // Load some data
require("register_form.php"); // Pass it to the view
And this posts to register_process.php
$username = $_REQUEST['username'];
$password = $_REQUEST['password'];
$email = $_REQUEST['email'];
Users::Register( $username, $password, $email );
header( 'location: register_success.php' );
MVC is not suitable for all applications, so you should consider your architecture on a per project basis. For many sites, just having a bunch of independent scripts works fine. For larger more complex applications however, MVC has proven itself to be a reliable and scalable way of developing web applications.
Another common design pattern is "View-Helper", which is where you call a template directly, and the template calls a "Helper" object that performs business logic between the template and the models. Similar in concept, but you can skip having any extra code for templates that don't need it, while still maintaining separation of concerns like MVC. (The difference is essentially that you call the template directly, rather than calling a controller).
There are several ways to implement a good application, but I am just going to touch on a few concepts. These concepts are taken from Samstyle PHP Framework.
Firstly, you have these components: Model (Table Data Gateway), View, View Controller and Backend Controller.
This View Controller actually controls how the view is going to be like (e.g. display out the registration form). The Backend Controller processes user data on the backend and interacts with the Model (database).
So here we can easily integrate Post-Redirect-Get into it.
Say you have register.php for the View Controller which will display the form and parse the content into the template HTML file.
User uses the form, submit and will then be posted to the Backend Controller deck.php. The Backend Controller validates, check then passes the data to functions (Table Data Gateway) which will help you to interact with the database. After the interaction is done, the user is redirected either to a success page, or the registration page with an error.
In the Model (Table Data Gateway), you actually have functions which take in an array and then CRUD with the database.
I am using Kohana but this question applies to Rails, CI, or any other MVC web development framework. Where is the best place to stick one's server side AJAX scripts?
I was planning on creating an Ajax_Controller and using a method/action per individual script.
For example, a login form on the home page index.php/home would send an XMLHttpRequest to index.php/ajax/login, and the edit profile form index.php/profile/edit would send an XMLHttpRequest to index.php/ajax/editprofile. What's the best practice?
I tend to put my ajax actions in the same controller as the non-ajax actions for any given model.
When I can, I try to use the same actions and only change the output type. Most tasks should have a non-ajax version anyway, so this tends to work quite well. Very handy for reducing logic duplication.
AJAX crosses all of the MVC boundaries. That is, it doesn't go into just one of model, view or controller.
Your AJAX scripts will be calling scripts on your site - so this would involve a section of your controller layer which you've created for the purpose.
That controller in turn would access the database using the interface provided by your model layer, just as a non-AJAX request would.
The data for the response back to the client may be packaged as JSON or XML or something. Technically this is the task of your view layer, though if your application's definition of a view layer is nothing more than "an HTML templating system" rather than "processing and formatting anything that gets sent back to the client whether it's HTML or something else like XML" then your XML or JSON generation may need to go into a new little section of its own.
As for sending the scripts (Javascript files) themselves, this is probably going to be handled directly by the web server rather than from within your MVC framework.
Do you make different controllers for GET and POST requests? I don't. In my opinion, JS requests shouldn't be dealt with differently either.
I personally see JS requests just like GET, POST or any other type of request. So if I have user-related JS-based actions, I simply create them in the user controller.
If you mean the AJAX (Javascript) scripts themselves, these should go into your public/js folder. However, if you mean the actions invoked by these AJAX requests, they should be treated as any other actions of the respective controllers. To be completely RESTful, you should be using a different format (json, xml, etc.) as return values for those actions.
I am a noob, but based on my understanding, to achieve ajax with php mvc... thinking steps might be:
change the definition/function of the existing php view layer from 'HTML template' into 'results formatting (XML,JSON etc..' -> results from relevant module, which then called by controller to output into AJAX object, then it means you need to write view layers into each particular class with formatting methods
PHP module layer stays same
build a Ajax router class with JS which stay the same structure which you route in your PHP
build a ajax results handler class with JS to handle the results got back from PHP controllers (XML JSON etc..), then from here do whatever user interactions you want, this will be called by above Ajax router class
So,
ajax router (send XMLhttprequest)
-> PHP controllers C
-> PHP module -> PHP view results M
-> PHP controllers output results V
-> ajax results handle (into page)
I don't use Kohana but what I do in my framework is that AJAX scripts are controllers. I try to treat them as standalone controllers but in the end they are just controllers.
Using a separate controller is a good idea. I either organize my controllers by function and then actions by return type.
Additionally, when I'm using Pylons I can decorate an action with #jsonify and that will automatically take care of converting python objects to JSON. Very handy.
I like to keep all my ajax requests in one controller, typically dispatching their requests through a shared model (that the non ajax controller also uses)
The main difference being the view that results via the ajax controller (html fragments, json data, etc) or the non-ajax controller (full pages)
You could wrap it up as a general REST-api, and use RESTful conventions and URIs.
Example:
Instead of index.php/ajax/editprofile it could be a PUT request to index.php/api/profile/profilename.