I have a website where people can place bids on products. So the first thing I have done is created a normal HTML-PHP version of the website which works great.
I have created some basic PHP functions that look at the url -> route you to the controller -> perform the action -> take the POST object etc.
Now I have implemented an AJAX version for this action but I want to know if I am doing the correct thing.
I made a new folder called ajax, and there I made a new controller for the ajax request. Now when somebody clicks on 'bid' then the request is hijacked by Javascript and sent to the AJAX controller. Now in the AJAX controller I strip down the link and then load the controller and model, and the work is done by the class.
Now the response the class has to send back is different for the AJAX version and for the HTML version. Now in the code of the class I have something like this
if(ajax version){
give ajax response
}else{
give html response
}
Now there are more things in the classes that are different.
Now my question is is it ok to use the same classes and config files for the ajax and non ajax function, or do they have to be seperate.
Or is there a more elegant manner of tackling this problem, maybe using interfaces.
If you follow the MVC pattern correctly, which it looks like from your description you are, then you should have a different action per request.
The flow should be
a different URL and action to receive the AJAX request
perform the business logic in your model
the action should then format the response in the style required (AJAX)
By having a switch (the if statement) in a shared controller, you run the risk of adding logic into the controller, which reduces the re-usability of your code.
So, put simply. Have a different PHP page for the different actions.
An easy way to do this is set a GET or POST parameter in the request when using AJAX, such as ajax=1 then check for this in the PHP:
if (isset($_GET['ajax'])){
give ajax response
} else {
give html response
}
AJAX requests have a header HTTP_X_REQUESTED_WITH with a value XMLHttpRequest
For example:
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){
// Ajax
} else {
// Normal request
}
As a rule of thumb, it is usually better to keep the same Model and Controller and, based on data in the request (such as a value in the query string, or a custom header such as X-Requested-By), switch Views (probably between an HTML Template View and a JSON View).
Related
I'm new to the world of API programming, I just have a bit of a side project at work at the moment and I'm learning as I write, so bear with me.
I'm unsure as to the best way to implement an API for multiple different functions. At the moment I just have a test script I run and an apache redirect that redirects anything under /api to this script, call it TestAPI.php (so /api/anything will redirect). I pass the path variable of the API to the script (so in that example the path would be 'anything').
At the moment I'm just writing it for 1 purpose, to look up some data based on the path, and eventually be about to update and delete etc with PUT/DELETE etc (it's restISH not restFUL). This is fine at the moment where everything redirects to this script, but what about if I need 2 different functions? So I want to look up a different data set? So for example now /api/data1 would go to the 1st set and /api/data2 would go to the second. This is where I start to get unsure.
Do I simply have 1 mega script that grows and grows so that /api/data1 and /api/data2 redirect to the same place (and thus handle any errors like 404s there). Or do I have a script for /api/data1 and /api/data2 with separate redirects to each, then a generic catchall for 404s (I would always like to return JSON/XML rather than HTML for a 404, so I need at least logic to return based on the Accept header).
As a 3rd option, do I have some sort of frontline controller that catches everything, then calls off to the sub components? So 1 script that is redirects to for anything under /api, which then calls off to the required components or 404s if it's an invalid path. This seems like the best way to do it to me, but I have no idea how. Do I have some section of the site that only that script can call, or do I use cURL from the frontline controller to the back end API sections (as I'd need to pass POST/PUT data I assume I'd have to use cURL, is there any other way?). How is this best implemented in Apache?
Yes, you use a front controller. The front controller can use convention like first thing after /api processes the request
i.e.
/api/firstprocessor/method1
/api/firstprocessor/method2
/api/secondprocessor/method14
You can check out Zend_Framework for an example of this in action, or it can be something as simple as
$name = 'Script_' . $this->generateCommandName($request->getPathVariable(1));
$this->executeScript($name, $request);
public function executeScript($class, Request $request) {
if (file_exists("scripts/".$class.'.php')) {
//include the script
require_once "scripts/".$class.'.php';
//execute the script
$command = new $class;
$command->execute($request);
}
}
Then all your scripts just have an execute method that uses $request to get $_GET or $_POST variables
For security purposes, I want to stop the users from being able to view or send anything to the php pages I am going to use for ajax purposes.
So is there any way by which I can check whether a page has been called because of an ajax request or the page has been opened?
Does self=top consider ajax request or not?
/* AJAX check */
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
/* special for ajax here */
}
else
{
//its a page request
}
this will only work when using JS frameworks that send this header :-by Bergi
No, you will need an other security model.
Of course you could set custom http headers (like X-Requested-With) or such when you are doing Ajax requests (many libraries do that automatically), and tell them apart from normal "view" requests. But everything can be faked, so there can be no security through determining that.
Even if you do stop people not using a ajax request, what's stopping people from changing the ajax request in the first place?
This would add little to none added security in my opinion especially with the ease this can be done with firebug for example.
Ive used a common approach to a custom MVC pattern
controller/action/param
$controller->action($param)
How can I implement a method of redirecting i.e. using header() because theres always an initial output from the main controller but Im not intentionally outputting anything.
NOT INTERESTED IN USING POPULAR FRAMEWORKS AND IM NOT TRYING TO REINVENT THE WHEEL JUST TRYING TO LEARN.
you can enable output buffering to store the initial output and flush it after the header function
ob_start();
echo "output";
header("Location: other.php");
ob_end_flush();
or you can use javascript to redirect:
echo '<script type="text/javascript">window.location='.$url.'</script>';
EDIT:
There is a common case when writing class, you accidentally leave a whitespace after the closing ?> tag, maybe it's causing the output.
to avoid such accidents just leave out the closing ?>, it's completely legal, unless you have only php in your file.
One way is to buffer all the output with ob_start functions. And in your redirect function you can use the header.
Another approach would be to send a meta tag for html redirect.
I wouldn't redirect, it is not necessary and may be time consuming (more requests, responses to/from the server)
I would use index.php (as a main controller) and handle any request to the server, then calling to the requested controller action and then calling the view to render the requested view, and finally the main controller sending the rendered view to the client.
Doing it this way you can use the index.php as a main controller or main app, and centralize anything you need to (segurity, cache, debug, logs).
In order to get the index controller handle every request you can use mod_rewrite.
This is one approach I did for my MVC, maybe this helps to you on understanding the flow (this is not the only one approach, check wikipedia or resources).
MAIN CONTROLLER: catches the request, and invokes the appropiate controller with the request data (POST / GET)
CONTROLLER: executes the action involved, calling models to retrieve the data, and sending the output data to the view, getting the output from the view and sending it back to the main controller.
MODEL: gets data from the database and operates it
VIEW: uses layouts, templates, and incoming data to build the html output
For example let's say I have a controller called News. Methods of News include Create, Edit, Delete, etc. So let's say for users with javascript enabled, we can use AJAX to deal with these things and use the controllers if not. For example, going to /news we can create news, edit, or delete without leaving this page...with AJAX. Without javascript, we would have to go to /news/create, /news/edit/1, /news/delete/1, etc.
So then what way is more efficient to deal with AJAX requests? On each controller should I just have a conditional to check whether the request was sent with AJAX, something like:
if(isset($_POST['ajax'])) {
// serve ajax request
} else {
// serve regular request
}
Or should I create additional methods such as ajaxCreate, ajaxEdit, ajaxDelete, etc?
Shouldn't your AJAX requests be almost the same as your regular requests, except the regular requests have an additional layer (rendering a page) on top?
Your conditional check should simply regulate whether you respond with something like a JSON response, or a full page - in effect, what view you invoke (assuming an MVC-style setup).
Never use /news/delete/1 to delete news!
use POST /news/delete and pass a news id
With that said, both ajax request and regular requests should be made to the same URL. the difference is that regular requests will return an html response and an ajax request will return xml/json/etc
Page: /news/create/
// create new news item code goes here
// most newer javascript libraries set this header so you know the page
// was requested via ajax
if ( isset( $_SERVER['X-Requested-With'] && $_SERVER['X-Requested-With'] == 'XMLHttpRequest' ) {
//output status code or new news item
exit;
}
// not an ajax request load a view
require( 'views/news_create.php' );
I prefer to pull this functionality into an API. For example, I can have a folder structure like the following:
web
- api
- 1.0
- news
create.php
news.php
Then your page is accessible at the 'news.php' URL. Inside this file you consume your own api. The AJAX would also directly access the API at the 'api/1.0/news/create.php' URL for instance.
This leads to less API code in the controllers/views.
Bob
After form (method POST) submission i want redirect user to specific page.
usually i used simple line
header("Location: /path/to/redirect/");
exit;
The Zend_Controller_Action have method _redirect example:
$this->_redirect("/path/to/redirect/");
But it have one simple problem: if i refresh page (press F5) last controller action is activated. So its like double post.
Of course i can use old fashion way, but I just want find the zend style redirect.
Edit: p.s after post redirect i want have cleaned form data. Of course i can use own method with header("location:/path") but I searching it implemented in standart zf
Any ideas?
I think thats because _redirect uses an internal redirect. You need to use an external one. You need to use the Redirector action helper directly... in your action:
$this->_redirector->gotoUrlAndExit($url);
Set a session variable that data has been posted, if not post data, redirect?