JSON and PHP: formatting and validating
Formatting JSON to look all lovely
It's always a happy day when I manage to use JSON in PHP. As a JS developer, it sort of feels like I'm marrying the two technologies. Take that, serialised arrays - I'm using JSON.
PHP, of course, has support for encoding and decoding JSON via json_encode() and json_decode() respectively. What it can't do natively, though, is format JSON.
Why would you want to format JSON in PHP to make it look all nice and indented? Well, if the system you're building uses JSON for a config file, and you want users to be able to edit that config file within the system, in a textarea, say.
I then found this function, which largely does the job.
It can, however, get the indentation wrong sometimes. Also, it can leave whitespace at the end of lines. So I extended it slightly. The following three snippets should be inserted just before the final return statement.
Firstly, let's clear any whitespace left at the end of lines.
$result = preg_replace('/\t+\n/', "\n", $result);
Next, let's fix the indentation. What I noticed was that the script was indenting lines containing closing brackets/braces precisely double what it should be - so four tabs instead of two, for example. So, the following halves each case.
1function PR_callback($match) { return substr($match[1], 0, strlen($match[1]) / 2).$match[2]; }
2$result = preg_replace_callback('/^(\t+)(\]|\})/m', 'PR_callback', $result);
Note I'm using a callback on preg_replace() - this gives me greater control over the nature of my replacements. preg_replace() automatically forwards to my callback one argument - an array of the match. As ever, key 0 in the array contains the whole match and any subsequent keys contain any sub-matches my pattern looked for.
Lastly, either the script or (more probably) my hacks above end up killing some of the line breaks, so let's restore them.
$result = preg_replace('/([^\t]+)\t/', "$1\n\t", $result);
Et voila - nicely formatted JSON.
Make sure your JSON's valid
JSON and JavaScript Object Notation are not always the same thing. How so? Well, this is valid JS but INvalid JSON:
1var someObj = {
2 one: 'one',
3 two: 'two'
4}
...because the JSON spec demands that a) property names are quoted; b) property names and strings must be encased in double, not single quotes.
So if you end up with invalid JSON, how will you know? PHP >= 5.3 defines json_last_error(), which returns a flag saying what went wrong.
Confusingly, it returns something even if nothing went wrong - JSON_ERROR_NONE. It does not return false, so it is insufficient to check the validity of JSON with:
1$badJSON = '{one: "one"}';
2$array = json_decode($badJSON, true); //2nd param means we get back an assoc. array, not an object
3if (!json_last_error()) echo "All OK!";
Instead, the last line should be:
if (json_last_error() != JSON_ERROR_NONE) echo "All OK!";
PHP versions prior to 5.3
If you're running PHP prior to v.5.3, you won't have json_last_error(). Instead, you can simply check the truthy/falsy value of json_decode(), so:
1$array = json_decode($badJSON, true);
2if (!$array) echo "Problem!";
Obviously this approach is more crude and won't tell you what went wrong - just that something did.
If you're looking for somewhere to host your PHP, whether Linux or Windows hosting, it always pays to make use of a good web hosting review site to find the right web hosting provider. This is a particularly good one, especially their WordPress hosting search page if you’re still on your way finding a suitable home for your WordPress blog.
post a commentOn-the-fly conversion of Flash to image for iOS
In this brave new world of smart phones and tablet PCs, the firm I work for is focusing a lot of energy these days on how to roll out its historical content onto these devices.
The problem is, over the years, we've made a lot of Flash banners. And iOS, the OS behind iPhone and iPad, doesn't support Flash.
I was charged with coming up with a solution. What's a quick way of generating static image equivalents of thousands of Flash banners?
I came up with a solution involving JS and PHP. The concept is this: as users browse our content on Flash-supporting PCs, a secret PHP script is loaded in a hidden iFrame that takes a screenshot of the page (yes, it can do this).
Data regarding the banner's position and dimensions is passed to the script by Javascript in the query string.
Works a treat. Though users don't realise it, they're helping us create a cache of images that are alternatives to Flash banners.
We did hit one snag, though. As I said, JS passes PHP the coordinates of the banner – but of course these coordinates are relative to the viewport – not the window, but PHP's screenshot is of the window, i.e. toolbars and all.
There is no way in PHP to capture the contents of a window – only the window, complete with toolbars and other periphirals.
IE actually provided a solution to this problem. It defines window.screenLeft and window.screenTop – respectively, the left and top position of the viewport relative to the window. Hurrah! But no… Firefox doesn't define these properties. Other browsers do, but give them other meaning, so no dice.
But there is a solution. A very hacky, almost whorish solution, but it works. I'll write a separate blog post in the next few days detailing the technical steps of this conundrum, in case it helps anyone else.
post a commentGD barchart generator
Just posted this in the script section. It's a script for generating bespoke barcharts. It's powered by PHP's superb GD library, which I've long loved using and which allows the creation of dynamic images via PHP.
Head over here to download, get usage info or view a demo.
The script gives you full control over how your chart looks, including the data displayed, the axis increments, the colours, font angle and much more.
post a commentUI for Postcode Anywhere address look-up
Just posted this in the scripts section. It's a user interface for the popular and very useful Postcode Anywhere address look-up service.
They seem to like it - they tweeted about it earlier.
Head over here to download, get usage info or view a demo.
The focus, as ever, is on integration. You set a few config vars, call the script into your page and that's it. You even need to prepare any elements; the look-up link or button is DOM-scripted into your page next to your postcode field, while returned addresses are displayed as links in a neat scrolling <div> that is DOM-scripted under your field.
post a commentcurveMe - cross-browser curvy corners
Curvy corners. Nice concept, shame about the lack of cross-browser method. You've got border-radius for Opera and a few others, -moz-webkit for Firefox, and, er, nowt for IE. Well, there's the jQuery curve() plugin, but that's not without its quirks and faults.
So I've built a plugin which enables curvy corners in all browsers, using a mixture of Javascript DOM-scripting and PHP GD (so make sure this is on your server; it's normally there by default).
Head over here to download, get usage info or view a demo.
It runs on any element that you give a particular class structure to, made up of a flag, the corner sizes and the colour of the border (if the latter isn't set, your border and curves will be the same colour as the element's computed background colour), i.e.
class='curveMe-20,20,20,20-#00659d'
Hello, world
Phew, so here we are. I finally launched. Welcome to my site, primarily a vehicle to promote and share the growing array of Javascript work and other scripts I write in my capacity as web developer in Hampshire.
Although I've historically been a back-end developer, my interest is more with JS/jQuery/AJAX. So that's what I'll be posting, though expect some sprinklings of PHP/MySQL too.
echo "hello, world!";
All my stuff is written with integration and customisation in mind right from the off; how often do you find a script you think solves a problem you have, only to find it doesn't quite work how you want - or at all?
I'll shortly be loading up the site with recent scripts, including a cross-browser curvey corners script (the existing curvey corners jQuery plugin has some quirks...), a fix for the age-old issue of IE running events on Window, not on the trigger element, and more...
post a comment



