容错file_get_contents

时间:2012-02-22 15:06:41

标签: php caching file-get-contents fault-tolerance

我的网站具有以下架构:

End user     --->    Server A (PHP)        --->        Server B (ASP.NET & Database)
             web                    file_get_contents
           browser                  

服务器A是一个简单的Web服务器,主要服务于静态HTML页面。但是,某些内容是动态的,并且此内容是从服务器B获取的。示例:

someDynamicPageOnServerA.php:
<html>
     ...static stuff...

     <?php echo file_get_contents("http://serverB/somePage.aspx?someParameter"); ?>

     ...more static stuff...
</html>

这很好用。但是,如果服务器B关闭(维护,意外崩溃等),则服务器A上的那些动态页面将失败。因此,我想

  • 缓存file_get_contents和
  • 的最后结果
  • 如果file_get_contents计时,则显示此结果。

现在,实现这样的事情应该不会太难;然而,这似乎是一个常见的情况,我想避免重新发明轮子。是否有一些PHP库或内置功能可以帮助实现这样的场景?

3 个答案:

答案 0 :(得分:2)

我会做这样的事情:

function GetServerStatus($site, $port){
    $fp = @fsockopen($site, $port, $errno, $errstr, 2);
    if (!$fp) {
       return false;
    } else { 
       return true;
    }
}

$tempfile = '/some/temp/file/path.txt';

if(GetServerStatus('ServerB',80)){
     $content = file_get_contents("http://serverB/somePage.aspx?someParameter");
     file_put_contents($tempfile,$content);
     echo $content;
}else{
     echo file_get_contents($tempfile);
}

答案 1 :(得分:0)

您可以检查文件的修改时间,只在不同时请求它,否则加载本地副本。此外,PHP网站上的filemtime注释中有一个缓存伪示例(来自:http://php.net/manual/en/function.filemtime.php):

<?php
$cache_file = 'URI to cache file';
$cache_life = '120'; //caching time, in seconds

$filemtime = @filemtime($cache_file);  // returns FALSE if file does not exist
if (!$filemtime or (time() - $filemtime >= $cache_life)){
    ob_start();
    resource_consuming_function();
    file_put_contents($cache_file,ob_get_flush());
}else{
    readfile($cache_file);
}
?>

答案 2 :(得分:0)

我接受了dom的答案,因为它是最有帮助的答案。我最后使用了一种稍微不同的方法,因为我想考虑通过端口80可以访问服务器的情况,但是其他一些问题阻止了它提供所请求的信息。

function GetCachedText($url, $cachefile, $timeout) {
    $context = stream_context_create(array(
     'http' => array('timeout' => $timeout)));  // set (short) timeout

    $contents = file_get_contents($url, false, $context);

    $status = explode(" ", $http_response_header[0]); // e.g. HTTP/1.1 200 OK
    if ($contents === false || $status[1] != "200") {
        $contents = file_get_contents($cachefile); // load from cache
    } else {
        file_put_contents($cachefile, $contents);  // update cache
    }
    return $contents;
}