How to Create an XML to JSON Proxy Server in PHP

Craig Buckler
Share

Unless you’re new to this web development lark, you’ll know the ‘X’ in ‘AJAX’ stands for XML — eXtensible Markup Language. But you’re probably not using XML. If you are, you’d probably prefer not to. All the cool kids are using JSON or JSON-P: it has a smaller payload, is easier to use and faster to process.

That’s not to say XML shouldn’t be used. It’s been around a long time and is well-supported by most languages — including JavaScript. If you’re sharing data between a variety of systems and platforms, XML is almost certainly the most practical choice. But that doesn’t ease your client-side coding efforts.

Fortunately, there are a couple of solutions which allow you to retain the benefits of XML data interchange but provide the ease of JSON in JavaScript. In this article, we’re going to create an XML to JSON proxy server in PHP.

That Sounds Complicated?

Don’t worry, it’s not. In essence, a proxy sits between the client and server passing messages between the two. You’re probably sitting behind a proxy now — they’re used on the internet to cache data and reduce network traffic. However, they can also process data; we will create a simple PHP proxy which translates XML messages to JSON before they reach your JavaScript code.

Proxy Plan

Our system will:

  1. Send an Ajax request from JavaScript which calls the PHP proxy. It will pass a single encoded URL as a GET parameter named ‘url’.
  2. The proxy will fetch the contents of the passed URL as a string, parse it as XML and convert it to JSON.
  3. The JSON string will be returned to the calling JavaScript process.

If necessary, we could create a full REST-aware proxy which parsed POST, PUT and DELETE parameters. But this simple solution will be adequate for 99% of Ajax queries and it has a few other advantages:

  • It’s possible to call web services on foreign domains — that’s not always possible with a JavaScript-only solution.
  • If necessary, the proxy could strip unnecessary data from the message to reduce the payload.
  • We’ll require less JavaScript code and it will execute faster.

The PHP

PHP provides support for both XML and JSON so creating our proxy, xmlproxy.php, is reassuringly simple.

That said, a lot can go wrong. Our script might fail, the remote service might go down, or the returned XML could be malformed. We don’t want PHP errors sent back to JavaScript so we’ll define an exception handler to hide them:


<?php
ini_set('display_errors', false);
set_exception_handler('ReturnError');

We now require two variables for the response ($r) and the passed URL ($url):


$r = '';
$url = (isset($_GET['url']) ? $_GET['url'] : null);

PHP’s cURL library is used to fetch content from the URL and pass it to string $r:


if ($url) {

	// fetch XML
	$c = curl_init();
	curl_setopt_array($c, array(
		CURLOPT_URL => $url,
		CURLOPT_HEADER => false,
		CURLOPT_TIMEOUT => 10,
		CURLOPT_RETURNTRANSFER => true
	));
	$r = curl_exec($c);
	curl_close($c);

}

Assuming something was returned, we’ll load it as a SimpleXMLElement object and return a JSON-encoded message:


if ($r) {
	// XML to JSON
	echo json_encode(new SimpleXMLElement($r));
}

If nothing was returned, we’ll call our exception handler function, ReturnError(), which outputs a JSON-encoded error flag:


else {
	// nothing returned?
	ReturnError();
}

// return JSON error flag
function ReturnError() {
	echo '{"error":true}';
}

The JavaScript

Our JavaScript must define the remote URL to call, e.g.


// example XML feed
var url = "http://domain.com/example.xml?status=123&date=2011-01-01";

The URL is appended to the PHP proxy address as a ‘url’ parameter and passed to the open() method of our XMLHttpRequest call (Ajax):


// AJAX request
var xhr = (window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"));
xhr.onreadystatechange = XHRhandler;
xhr.open("GET", "xmlproxy.php?url=" + escape(url), true);
xhr.send(null);

Finally, our XMLHttpRequest onreadystatechange handler receives the data and converts the JSON string to a real JavaScript object:


// handle response
function XHRhandler() {

	if (xhr.readyState == 4) {
	
		// parse response as JSON
		var json;
		if (JSON && JSON.parse) {
			json = JSON.parse(xhr.responseText);
		}
		else {
			eval("var json = " + xhr.responseText);
		}
		
		// do something with our returned JSON data...
		console.log(json);
		
		xhr = null;
	
	}

}

Please download the code, extract the files to your PHP-enabled web server, and open proxy.html in a browser.

A Note About XML Attribute Encoding

XML has a richer syntax than JSON and data can be encoded as elements or attributes — even with the same name, e.g.


<?xml version="1.0"?>
<statuses>
	<status id="one">
		<id>1</id>
	</status>
</statuses>

The PHP json_encode function translates attributes to a separate ‘@attributes’ object, i.e.


{
	"status": {
		"@attributes": { "id": "one" },
		"id": "1"
	}
}

I hope you find the code useful. It allows you to have your XML cake and consume it as JSON!