You are here:  » Caching multiple xml files on the same page.


Caching multiple xml files on the same page.

Submitted by Barbabara on Mon, 2011-08-22 10:39 in

Hi,
I am currently using the caching function -

<?php
function cacheFetch($url,$age)
  {
    
$cacheDir "cache/";
    
$filename $cacheDir.md5($url);
    
$fetch true;
    if (
file_exists($filename))
    {
      
$fetch = (filemtime($filename) < (time()-$age));
    }
    if (
$fetch)
    {
      
exec("wget -N -O ".$filename." \"".$url."\"");
      
exec("touch ".$filename);
    }
    return 
$filename;
  }
?>

How could i modify the function to cache multiple xml files on the same Page?

Also, I know that a file exists in the cache directory, however, when the external site from which the file was originally requested is down, the cached file will not load.

Surely, the function will fetch the file from cache, if it exists, without visiting the external site! The age to cache the file has been set.

Thanks

Barbara

Submitted by support on Mon, 2011-08-22 13:52

Hi Barbara,

There shouldn't be able problem calling cacheFetch for multiple files on the same page; bear in mind of course that if the files require parsing differently, e.g. different record handler functions then you might require something like this:

function myRecordHandler1($record)
{
  // display record type 1
}
function myRecordHandler2($record)
{
  // display record type 2
}
$url1 = "http://www.example.com/data1.xml";
$url2 = "http://www.example.net/data2.xml";
MagicParser_parse(cacheFetch($url1),"myRecordHandler1","xml|FORMAT/STRING/");
MagicParser_parse(cacheFetch($url2),"myRecordHandler2","xml|FORMAT/STRING/");

However, the problem you're describing sounds perhaps like the age had been reached, but the remote site was down so the cached good copy was overwritten with an empty file. To protect against this possibility; try this as an alternative;

function cacheFetch($url,$age)
  {
    $cacheDir = "cache/";
    $filename = $cacheDir.md5($url);
    $fetch = true;
    if (file_exists($filename))
    {
      $fetch = (filemtime($filename) < (time()-$age));
    }
    if ($fetch)
    {
      exec("wget -N -O ".$filename.".tmp \"".$url."\"");
      if (filesize($filename.".tmp"))
      {
        rename($filename.".tmp",$filename);
        exec("touch ".$filename);
      }
      else
      {
        unlink($filename.".tmp");
      }
    }
    return $filename;
  }

Hope this helps!
Cheers,
David

Submitted by Barbabara on Wed, 2011-08-24 10:30

Hi David,

Thanks for your previous reply.

Is it possible to timeout the call for the external xml file within the function you have provided?

If the external server is down the web pages calling the xml file take forever to load.

Thanks

Barbara

Submitted by support on Wed, 2011-08-24 11:03

Hi Barbara,

Sure - you can set a timeout on the wget request. In place of this line:

      exec("wget -N -O ".$filename.".tmp \"".$url."\"");

...have a go with:

      exec("wget -T 10 -N -O ".$filename.".tmp \"".$url."\"");

...for a 10 second timeout.

Cheers,
David.

Submitted by Barbabara on Mon, 2011-09-05 09:08

Hi David,

Is it possible to alter the caching solution to cache the actual 'filename' without using md5 hash.

<?php
function cacheFetch($url,$age)
  {
    
$cacheDir "cache/";
    
$filename $cacheDir.md5($url);
    
$fetch true;
    if (
file_exists($filename))
    {
      
$fetch = (filemtime($filename) < (time()-$age));
    }
    if (
$fetch)
    {
      
exec("wget -N -O ".$filename." \"".$url."\"");
      
exec("touch ".$filename);
    }
    return 
$filename;
  }
?>

Thanks

Barbara

Submitted by support on Mon, 2011-09-05 09:16

Hi Barbara,

One way to do that would be to explode() the URL and take the last section which should be the remote filename. Within the cacheFetch function, where you have this code:

$filename = $cacheDir.md5($url);

...REPLACE with:

$parts = explode("/",$url);
$filename = $cacheDir.$parts[(count($parts)-1)];

Bear in mind however that it's not necessarily the case that the final part of the URL is a clean filename. It would work fine for URLs such as:

http://www.example.com/feeds/filename.xml

However not really suitable for:

http://www.example.com/feed.asp?id=1234

Cheers,
David.