PHP中的5分钟文件缓存

hyp*_*not 27 php url curl download

我有一个非常简单的问题:在PHP中下载文件的最佳方法是什么,但只有在超过5分钟之前下载了本地版本?

在我的实际情况中,我想从远程托管的csv文件中获取数据,我目前正在使用它

$file = file_get_contents($url);
Run Code Online (Sandbox Code Playgroud)

没有任何本地副本或缓存.将此转换为缓存版本的最简单方法是什么,最终结果不会改变($ file保持不变),但如果不久前(例如5分钟)取出它,它会使用本地副本?

Mat*_*son 66

使用本地缓存文件,并在使用之前检查文件的存在和修改时间.例如,if $cache_file是本地缓存文件名:

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);
}
Run Code Online (Sandbox Code Playgroud)

(未经测试,但基于我目前使用的代码.)

无论哪种方式通过此代码,$ file都会以您需要的数据结束,如果它是新的,它将使用缓存,或者从远程服务器获取数据并刷新缓存(如果不是).

编辑:自从我上面写了以后,我对文件锁定有了更多的了解.如果你担心这里的文件锁定,可能值得阅读这个答案.

如果您担心锁定和并发访问,我会说最干净的解决方案是将file_put_contents写入临时文件,然后rename()结束$cache_file,这应该是一个原子操作,$cache_file即将是旧内容或全新内容内容,从来没有写过.

  • @Volomike据我了解,在统计缓存在每个脚本运行开始清除,所以只要你不调用这个方法在同一脚本中多次,它应该是罚款.(我只是检查,并在[filestat.c(https://github.com/php/php-src/blob/4b943c9c0dd4114adc78416c5241f11ad5c98a80/ext/standard/filestat.c),你会看到STAT高速缓存中被清除`PHP_RINIT_FUNCTION`回调,所以它肯定会在每个请求开始时重置.) (2认同)

Ken*_* Le 7

尝试phpFastCache,它支持文件缓存,而且您不需要编写缓存类.易于在共享主机和VPS上使用

这是一个例子:

<?php

// change files to memcached, wincache, xcache, apc, files, sqlite
$cache = phpFastCache("files");

$content = $cache->get($url);

if($content == null) {
     $content = file_get_contents($url);
     // 300 = 5 minutes 
     $cache->set($url, $content, 300);
}

// use ur $content here
echo $content;
Run Code Online (Sandbox Code Playgroud)