Muhambi
Muhambi

Reputation: 3522

Cache Weather in PHP

My code:

<? 
    $url = 'http://w1.weather.gov/xml/current_obs/KGJT.xml'; 
    $xml = simplexml_load_file($url); 
?>

<? 
    echo $xml->weather, " ";
    echo $xml->temperature_string;
?>

This works great, but I read that caching external data is a must for page speed. How can I cache this for lets say 5 hours?

I looked into ob_start(), is this what I should use?

Upvotes: 0

Views: 235

Answers (2)

Marc B
Marc B

Reputation: 360602

The ob system is for in-script cacheing. It's not useful for persistent multi invocation caching.

To do this properly, you'd write the resulting xml out of a file. Every time the script runs, you'd check the last updated time on that file. if it's > 5 hours, you fetch/save a fresh copy.

e.g.

$file = 'weather.xml';
if (filemtime($file) < (time() - 5*60*60)) {
    $xml = file_get_contents('http://w1.weather.gov/xml/current_obs/KGJT.xml');
    file_put_contents($file, $xml);
}
$xml = simplexml_load_file($file); 

echo $xml->weather, " ";
echo $xml->temperature_string;

Upvotes: 1

Patrick Moore
Patrick Moore

Reputation: 13344

ob_start would not be a great solution. That only applies when you need to modify or flush the output buffer. Your XML returned data is not being sent to the buffer, so no need for those calls.

Here's one solution, which I've used in the past. Does not require MySQL or any database, as data is stored in a flat file.

$last_cache = -1;
$last_cache = @filemtime( 'weather_cache.txt' ); // Get last modified date stamp of file
if ($last_cache == -1){ // If date stamp unattainable, set to the future
    $since_last_cache = time() * 9;
} else $since_last_cache = time() - $last_cache; // Measure seconds since cache last set

if ( $since_last_cache >= ( 3600 * 5) ){ // If it's been 5 hours or more since we last cached...

    $url = 'http://w1.weather.gov/xml/current_obs/KGJT.xml'; // Pull in the weather
    $xml = simplexml_load_file($url); 

        $weather = $xml->weather . " " . $xml->temperature_string;

    $fp = fopen( 'weather_cache.txt', 'a+' ); // Write weather data to cache file
    if ($fp){
        if (flock($fp, LOCK_EX)) {
           ftruncate($fp, 0);
           fwrite($fp, "\r\n" . $weather );
           flock($fp, LOCK_UN);
        }
        fclose($fp);
    }
}

include_once('weather_cache.txt'); // Include the weather data cache

Upvotes: 1

Related Questions