Creating a JSONP Data Provider in PHP
PHP 5.2 or PECL json 1.2 has the ability to convert data structures into JSON:
$data = array('zero', 'one', 'two', 'three'); $json = json_encode($data); echo $json
However, if you are deploying to a lowered PHP version, either because your hosting provider hasn’t caught up or you’re using Red Hat Enterprise (even the latest 5.3 only has PHP 5.1.2), then you need an alternate solution. I’ve visited http://www.json.org and found a good package: PEAR::Services_JSON (aka pear install Services_JSON). Although it’s in the beta channel, I’ve had good luck with it.
The equivalent code to the above is:
require('Services/JSON.php'); $data = array('zero', 'one', 'two', 'three'); $encoder = new Services_JSON(); $json = $encoder->encode($data); echo $json;
So, that is how you get a JSON string. What if you want to actually emit the JSON in an AJAX-ically useful way? Just add the PHP header function:
require('Services/JSON.php'); $data = array('zero', 'one', 'two', 'three'); $encoder = new Services_JSON(); $json = $encoder->encode($data); header("Content-type: application/json"); echo $json;
Now, for the final touch. Turning out standard JSON into JSONP. The only difference is that we need a JavaScript function definition wrapping the code:
require('Services/JSON.php'); $data = array('zero', 'one', 'two', 'three'); $encoder = new Services_JSON(); $json = $encoder->encode($data); header("Content-type: application/json"); echo 'callbackname (' . $json . ');';
We’ve added a function wrapper around the JSON. That allows for the data to be retrieved using the jQuery API. However, we can’t hard code the callbackname as you see above. We need to use the passed in value from jQuery.
$(function() { $.getJSON('provider.php?callback=?', {}, // No additional parameters sent function (data) { // data is now JSON object instantiated from retrieved info alert(data[0]) // Will show 'zero' in the alert that pops up }) }); });
That strange second question mark in the URL will be replaced by a jQuery created random number string that is expected to be returned in your callback name.
Save the code below as provider.php:
require('Services/JSON.php'); $data = array('zero', 'one', 'two', 'three'); $encoder = new Services_JSON(); $json = $encoder->encode($data); header("Content-type: application/json"); echo $_GET['callback'] . ' (' . $json . ');';
If you are using the outstanding Firebug add-on for Firefox, you’ll be able to see the GET request made by the page containing the jQuery code as well as the JSONP response from the script.
Why go through this trouble? Because we can now put provider.php on any server, regardless of whether the page calling provider.php is in the same domain or not. JSONP gets around the normal AJAX “same domain” restriction.
Now that we have our own provider, we can create simple arrays, complex arrays, and even objects that can be turned into JSON and sent to jQuery enabled pages, regardless of domain.
For additional information, see this IBM Developerworks article. It lists some of the existing JSONP services, including the URL to use with the jQUERY ajax invocations.
Great post! Just wanted to let you know you have a new subscriber- me!
The article is usefull for me. I’ll be coming back to your blog.
I really like your post. Does it copyright protected?
I own the copyright for my blog post, as is standard with U.S. copyright law. That being said, there’s nothing here I wouldn’t mind anyone using for their own purposes. Please consider the code available for use by anyone. use it and enjoy.
Hi. I like the way you write. Will you post some more articles?
Saved my life! Thank you.
Thank you. I spent the better part of the day looking for a specific example that didn’t leave off some important part. Your example was the only one that I found. Including line 5. and 6. were important and left out of almost every other PHP example. Thanks a bunch!
This isn’t work on different port?
This was really helpful. Thanks. I’d been looking around for a while for an explanation of the php required to get a json service going. i was all set with the javascript, but the php was mystifying to me.
[…] http://www.carolinamantis.com/wordpress/?p=29 AKPC_IDS += "1589,"; Share Tweet […]
your code won’t work crossdomain! you are missing
header(‘Access-Control-Allow-Origin: *’);
please update
regards pete
This is the best explanation by far I’ve found covering the business of hooking up the JSONP stuff in PHP/jQuery fashion. Examples are short and concise, pointing out exactly what matters – the callback, the wrapper, the header. Only thing, two and a half years on, is I guess you could drop the stuff about the PEAR package for old PHP versions. But then again, it’s easy to gloss over that.
Oh, and Peter’s wrong about the origin-header. Internet Explorer (9- at least) doesn’t even understand that, so exactly that is a very good reason to implement JSONP to allow cross-domain. For people who can’t do the JSONP stuff, perhaps because you cannot get it from your source, a proxy implementation is the best solution, and this is a good article about it: http://benalman.com/projects/php-simple-proxy/
Thanks, Kasimir for the kind words. I was investigating the same origin header information, but knew that my JSONP implementation worked without having to reconfigure my web servers.
Big thank you for the PHP proxy code, that’s really nice, and much better than the simple code I posted!
Its really nice.. I have searched all over google for this issue. Every 1 telling to use jsonp and callback=?. You said what change we have to do with php code to work fine.. Thank You.