When you are consuming XML through web services, it can translate into a lot of calls going back and forth to a remote server. For some pages or web apps, that may not be a big deal. For extremely data intensive apps, its often best to cache these XML datasets locally to help improve performance of our pages. Not to mention, some data providers don’t want you nailing their servers several thousand times a minute.

For me, I wanted to see if I could get a slight performance bump by storing this XML data locally. Since I don’t do much with XML these days, my research started with caching JSON in PHP, and I ran across this post on Stackoverflow. I made a few key changes to get this working for my needs (see the code implementation below).

First, I pointed the $cacheFile to an actual directory instead of saving it to our current directory. Also the original poster had this saving out as ‘cache/abcdef1235’. I liked pulling the hash value, but the cache element didn’t have a whole lot of use, and I thought it best to actually set the .xml file extension.

Second, they were writing the last modified date out to the first line of the file. This didn’t make a whole lot of sense since you could easily pull the last modified date off the file properties itself using filemtime(). That change cleaned the code up a bit.

Third, they were using the fopen() to read the file stream back. The method call was incorrect on this and should have looked something like this

fread($file,filesize("test.xml")); 

The larger problem was that there was a limit to how much the fread() could hold. Pulling back this large xml stream inevitably overflowed its capacity. It turns out the file_get_contents() was the better way to go.

Outside of that, I just included a few echo statements to verify we were dropping into the correct portions of the code. Thanks to deceze over on SO for helping kick this post off, and hopefully some will find this useful in future projects.

Method to cache the xml file

function getJson($url) {
    // cache files are created like abcdef123456...
	$cacheFile = "/directory_structure/xml/" . md5($url) . ".xml";

	echo "";
    if (file_exists($cacheFile)) {
        $fh = fopen($cacheFile, 'r');
		$cacheTime = filemtime($cacheFile);
		echo "";

        // if data was cached recently, return cached data
        if ($cacheTime > strtotime('-1 day')) {
			echo "";
			$response = file_get_contents($cacheFile);
			return $response;
        }

        // else delete cache file
        fclose($fh);
        unlink($cacheFile);
    }

	$json = file_get_contents($url);

    $fh = fopen($cacheFile, 'a+');//w
    fwrite($fh, $json);
    fclose($fh);
	echo "";
    return $json;
}

Call of method

$response = getJson($url);
$sx = simplexml_load_string($response);