Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

5-minute file cache in PHP

I have a very simple question: what is the best way to download a file in PHP but only if a local version has been downloaded more than 5 minute ago?

In my actual case I would like to get data from a remotely hosted csv file, for which I currently use

$file = file_get_contents($url); 

without any local copy or caching. What is the simplest way to convert this into a cached version, where the end result doesn't change ($file stays the same), but it uses a local copy if it’s been fetched not so long ago (say 5 minute)?

like image 286
hyperknot Avatar asked Mar 10 '11 16:03

hyperknot


People also ask

Do PHP files get cached?

The Windows Cache Extension for PHP includes a file cache that is used to store the content of the PHP script files in shared memory, which reduces the amount of file system operations performed by PHP engine. Resolve File Path Cache - PHP scripts very often include or operate with files by using relative file paths.

What is PHP cache?

A cache is a collection of duplicate data, where the original data is expensive to fetch or compute (usually in terms of access time) relative to the cache. In PHP, caching is used to minimize page generation time.


Video Answer


1 Answers

Use a local cache file, and just check the existence and modification time on the file before you use it. For example, if $cache_file is a local cache filename:

if (file_exists($cache_file) && (filemtime($cache_file) > (time() - 60 * 5 ))) {    // Cache file is less than five minutes old.     // Don't bother refreshing, just use the file as-is.    $file = file_get_contents($cache_file); } else {    // Our cache is out-of-date, so load the data from our remote server,    // and also save it over our cache for next time.    $file = file_get_contents($url);    file_put_contents($cache_file, $file, LOCK_EX); } 

(Untested, but based on code I use at the moment.)

Either way through this code, $file ends up as the data you need, and it'll either use the cache if it's fresh, or grab the data from the remote server and refresh the cache if not.

EDIT: I understand a bit more about file locking since I wrote the above. It might be worth having a read of this answer if you're concerned about the file locking here.

If you're concerned about locking and concurrent access, I'd say the cleanest solution would be to file_put_contents to a temporary file, then rename() it over $cache_file, which should be an atomic operation, i.e. the $cache_file will either be the old contents or the full new contents, never halfway written.

like image 59
Matt Gibson Avatar answered Sep 23 '22 17:09

Matt Gibson