0

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?

2
  • Does the remote server somehow indicate for how long you can/should cache the resource? Commented May 29, 2010 at 7:55
  • No, I'm just wondering how people tend to handle this. I'm thinking a cron tab is probably the way to go. Commented May 29, 2010 at 8:06

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Doesn't crontab execute scheduled tasks? Are you suggesting it call copy() every n minutes? I guess I don't understand "unconditionally" Does crontab have copy functions?
"unconditionally" means "regardless of any circumstances" or, in other words, "always." Every 5 minutes you update the file, no matter what. As for crontab, it executes stuff. You could make it run wget -O /path/to/cache/file.xml http://url.test or run a PHP script that retrieves the resource.
0

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");

Comments

0

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);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.