【问题标题】:How can I force PHP's fopen() to return the current version of a web page?如何强制 PHP 的 fopen() 返回网页的当前版本?
【发布时间】:2010-05-02 02:48:59
【问题描述】:

this google docs page当前内容为:

alt text http://www.deviantsart.com/upload/i9k01q.png

但是,当使用以下 PHP fopen() 脚本阅读此页面时,我得到了一个较旧的缓存 版本:


(来源:deviantsart.com

我尝试了this question 中提出的两种解决方案(一个随机属性并使用 POST),我也尝试了 clearstatcache(),但我总是得到网页的缓存版本。

我必须在以下脚本中进行哪些更改才能使 fopen() 返回网页的当前版本?

<?php
$url = 'http://docs.google.com/View?id=dc7gj86r_32g68627ff&amp;rand=' . getRandomDigits(10);

echo $url . '<hr/>';
echo loadFile($url);

function loadFile($sFilename) {
    clearstatcache();
    if (floatval(phpversion()) >= 4.3) {
        $sData = file_get_contents($sFilename);
    } else {
        if (!file_exists($sFilename)) return -3;

        $opts = array('http' =>
          array(
            'method'  => 'POST',
            'content'=>''
          )
        );
        $context  = stream_context_create($opts);                

        $rHandle = fopen($sFilename, 'r', $context);
        if (!$rHandle) return -2;

        $sData = '';
        while(!feof($rHandle))
            $sData .= fread($rHandle, filesize($sFilename));
        fclose($rHandle);
    }
    return $sData;
}

function getRandomDigits($numberOfDigits) {
 $r = "";
 for($i=1; $i<=$numberOfDigits; $i++) {
  $nr=rand(0,9);
  $r .=  $nr;
 }
 return $r;
}

?>

添加:取出 $opts$context 也会给我一个缓存页面:

function loadFile($sFilename) {
    if (floatval(phpversion()) >= 4.3) {
        $sData = file_get_contents($sFilename);
    } else {
        if (!file_exists($sFilename)) return -3;              

        $rHandle = fopen($sFilename, 'r');
        if (!$rHandle) return -2;

        $sData = '';
        while(!feof($rHandle))
            $sData .= fread($rHandle, filesize($sFilename));
        fclose($rHandle);
    }
    return $sData;
}

添加:这个发送 Firefox 用户代理的 curl 脚本也返回缓存版本:

<?php
$url = 'http://docs.google.com/View?id=dc7gj86r_32g68627ff';
//$user_agent = 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)';
$user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3 (.NET CLR 3.5.30729)';
$ch = curl_init();
//curl_setopt($ch, CURLOPT_COOKIEJAR, "/tmp/cookie");
//curl_setopt($ch, CURLOPT_COOKIEFILE, "/tmp/cookie");
curl_setopt($ch, CURLOPT_URL, $url ); 
curl_setopt($ch, CURLOPT_FAILONERROR, 1); 
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); 
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
curl_setopt($ch, CURLOPT_VERBOSE, 0);
echo curl_exec($ch);
?>

【问题讨论】:

    标签: php caching fopen google-docs http-caching


    【解决方案1】:

    我已经成功复制了这个。当您不是已发布 Web 文档的所有者时,Google 会进行缓存。如果您注销,它会给我旧版本。

    在我取消发布并重新发布后,我无法再重现该问题。确保在更新时继续在“共享为网页”下发布文档。

    只是为了确保检查未登录的浏览器(或您的脚本)。如果没有更新:取消发布并再次发布。它并没有为我更改 URL。

    【讨论】:

    • +1,很好。他的 Firefox 和 Chrome 浏览器设置了 cookie。它必须是与那个或谷歌相关的东西——或者在这种情况下两者兼而有之。
    【解决方案2】:

    我也明白了:

    Test One;http://docs.google.com/View?id=dc7gj86r_30dzgzbjch
    Test Two;http://docs.google.com/View?id=dc7gj86r_31dbssfrzx
    

    “缓存”必须在 Google Docs 中完成,或者更有可能是您的错(错误的 URL?)。


    响应标头:

    Set-Cookie: ******
    Content-Type: text/html; charset=UTF-8
    Cache-Control: no-cache, no-store, max-age=0, must-revalidate
    Pragma: no-cache
    Expires: Fri, 01 Jan 1990 00:00:00 GMT
    Date: Sun, 02 May 2010 03:30:29 GMT
    X-Frame-Options: ALLOWALL
    Content-Encoding: gzip
    X-Content-Type-Options: nosniff
    X-XSS-Protection: 1; mode=block
    Content-Length: 3987
    Server: GSE
    

    【讨论】:

    • 是的,我敢打赌,当您获得缓存版本时,您使用的是 Internet Explorer,对吗?我在 Firefox 和 Chrome 中获得了 CURRENT 版本,但在 IE8 中获得了 CACHED 版本,如下所示:stackoverflow.com/questions/2742258/…,所以当然,既然 Firefox 和 Chrome(webkit?)确实可以获得当前版本,fopen 中必须有一些选项( ) 还强制谷歌文档提供当前版本。
    • @Edward:不,在这里运行 Firefox 3.6.3,我之前从未使用任何浏览器访问过该 URL。相信我:这是你的错
    • @Edward:你有没有想过在 Firefox 和 Chrome 中按 CTRL+F5?!
    • 我的 FF 和 chrome 始终为我提供当前版本(我刚刚再次更新),IE8 中的 SAME url 为我提供了旧版本,就像上面的 Curl 脚本和 fopen() 脚本一样。是的,我在所有浏览器中都尝试过 CTRL+F5,但是 FF/Chromes 提供了新版本,IE8 旧版本。 Google Docs 会发送什么样的标头,导致各种浏览器中的版本如此不一致?
    • 有趣:在第二台机器上 FF 和 IE8 都显示旧版本,这是怎么回事?为什么新版本的文档会在一台机器上的两个浏览器中出现并且始终一致地出现?
    【解决方案3】:

    尝试确保您的浏览器没有缓存信息。我没有看到任何缓存标头或任何东西。您的网络服务器可能正在添加某些内容,或者您​​的浏览器可能假设它已被缓存。尝试在输出中包含时间,以便确保请求是在正确的时间生成的。

    我在几年前使用 fopen 来处理经常更新的数据。从来没有遇到过 fopen 的缓存问题。事实上,如果 PHP 开发人员在 fopen 中添加一个 Web 缓存,我会感到失望,因为它会破坏大多数有效的用例并且它不在他们的文档中。我会去看看 PHP 源代码来确定一下。

    您能否更新文档,以便我们中的一些人可以尝试复制?

    【讨论】:

    • 谢谢,我再次更新了文档,但是 fopen() 脚本与我的浏览器无关,我确信我可以在 Internet Explorer 中找到一些设置来清除它的缓存以便它显示当前版本,就像我的 Firefox 和 Chrome 一样,但我需要开始工作的是脚本,显然 Google Docs 正在做某种选择性缓存,但我想知道的是为什么它为我的 Firefox 浏览器提供了一个新版本,但我的(刚刚添加)curl 脚本上面有一个 firefox 用户代理一个旧版本,我可以更改 curl/fopen 中的哪些其他设置来强制一个新版本?
    • 查看我的其他答案,但基本上这是确保问题不是您的计算机缓存您制作的脚本(不是谷歌文档页面)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-25
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多