rrrfusco
rrrfusco

Reputation: 1119

Retrieve remote XML data with PHP

I'm currently reading a regularly updated XML file with PHP (simpleXML).

I'd like to reduce calls to the remote server by reading a cache file on my web server, then after some time, retrieve a new copy of the remote file.

Is this an accepted practice for reading remote XML files, then parsing? Can anyone offer some suggestions on how to go about this in PHP, or perhaps there are some PEAR classes that deal with this?

Upvotes: 0

Views: 4038

Answers (3)

user352353
user352353

Reputation:

If you are using Flash with AS3 (ActionScript 3) you could do something like an URLRequest to the given address...

I supose you have already the PHP file...

lets say is something like

<?php
 $lstrXML = "";
 $lstrXML .= "<?xml version="1.0"?>";
 $lstrXML .= "<root>";
 $lstrXML .= "<node1>";
 $lstrXML .= "<data cd='1' ds='a' />";
 $lstrXML .= "<data cd='1' ds='a' />";
 $lstrXML .= "<data cd='1' ds='a' />";
 $lstrXML .= "<data cd='1' ds='a' />";
 $lstrXML .= "</node1>";
 $lstrXML .= "</root>";

 echo($lstrXML);
?>

And in AS3... somewhere...

var xmlLoader:URLLoader = new URLLoader();
var xmlData:XML = new XML();
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
xmlLoader.load(new URLRequest("xmltest.php"));
function LoadXML(e:Event):void
{
    xmlData = new XML(e.target.data);
}

Upvotes: 0

Josh Davis
Josh Davis

Reputation: 28730

Yes, that's more than an accepted practice, it's a recommended one when dealing with remote resources.

There are general-purpose cache managers in PEAR and other librairies, but in your case a simple homemade solution would work just as well. Something like that:

function get_xml($url, $max_age)
{
    $file = '/path/to/cache/dir/' . md5($url);

    if (file_exists($file)
     && filemtime($file) >= time() - $max_age)
    {
        // the cache file exists and is fresh enough
        return simplexml_load_file($file);
    }

    $xml = file_get_contents($url);
    file_put_contents($file, $xml);
    return simplexml_load_string($xml);
}

Come to think of it, you could use copy() to retrieve the resource. In most cases it wouldn't make any difference but it's slightly more gentle on PHP's memory manager if the external resource just happen to be very big. But even then, if you're loading a huge XML to memory you have bigger problems than the way you download it :)

function get_xml($url, $max_age)
{
    $file = '/path/to/cache/dir/' . md5($url);

    if (!file_exists($file)
     || filemtime($file) < time() - $max_age)
    {
        // the cache file doesn't exists or is not fresh enough
        copy($url, $file);
    }

    return simplexml_load_file($file);
}

Oh, and I almost forgot. There's a better, easier way to do that if you have access to some cron feature. Just set up a cron job that unconditionally download that remote resource every 5 or 10 minutes. Then, let your PHP script unconditionally read from the cache file and not bother about the remote resource at all. This way, there's no "worst case" scenario in terms of latency. Otherwise, everytime your script refreshes your cache, it makes the user wait noticably more than if it got fetched from the cache.

Upvotes: 2

Emil Vikstr&#246;m
Emil Vikstr&#246;m

Reputation: 91902

Maybe something like this? Fetch the XML file from the server if there are no cache file or if the cache is expired (in this case more than ten minutes old).

$filename = 'myxmlfile.xml';
if(!file_exists("cache/$filename") || filemtime("cache/$filename") - time() > 600) {
  $f1 = fopen("http://example.com/rss.xml", 'r');
  $f2 = fopen("cache/$filename", 'w');
  while(!feof($f1)) {
    fwrite($f2, fread($f1, 8192));
  }
  fclose($f1);
  fclose($f2);
}

$doc = simplexml_load_file("cache/$filename");

Upvotes: 0

Related Questions