【问题标题】:PHP cURL - opt ifmodsice returns http code = 200PHP cURL - 选择 ifmodsice 返回 http 代码 = 200
【发布时间】:2014-12-08 10:16:36
【问题描述】:

我正在尝试设置一个 curl 请求,仅当它们在我存储的时间戳之后被修改时才获取远程文件。

我想管理我的 cURL 请求的 http 代码,这里是一个例子。

我存储了上次下载文件 XX 的时间戳。 2014-12-08 06:56:03。 我的 cURL 请求

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_FILETIME, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_TIMEVALUE, strtotime($timestamp));
curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
$res = curl_exec($ch);
$info = curl_getinfo($ch);

正如documentation 所说

CURLOPT_TIMECONDITION

如何处理 CURLOPT_TIMEVALUE。使用 CURL_TIMECOND_IFMODSINCE 仅当页面自 CURLOPT_TIMEVALUE 中指定的时间以来已被修改时才返回该页面。如果尚未修改,则假定 CURLOPT_HEADER 为 TRUE,将返回“304 Not Modified”标头。使用 CURL_TIMECOND_IFUNMODSINCE 获得相反的效果。 CURL_TIMECOND_IFMODSINCE 是默认值。

所以,如果我的时间戳是 2014-12-08 06:56:03 并且远程文件的文件时间是 2014-12-08 04:59:03 它必须返回一个 304 的 http 代码,但我总是得到一个 200 的 http 代码。 我误解了文档吗?

这些是以秒为单位的时间戳

  • 本地文件1418021941
  • 远程文件1418014742

这是上述 curl 请求的信息

array(26) {
  ["url"]=> string(32) "XXX"
  ["content_type"]=> string(24) "application/octet-stream"
  ["http_code"]=> int(200)
  ["header_size"]=> int(251)
  ["request_size"]=> int(113)
  ["filetime"]=> int(1418014742)
  ["ssl_verify_result"]=> int(0)
  ["redirect_count"]=> int(0)
  ["total_time"]=> float(0.100412)
  ["namelookup_time"]=> float(0.010285)
  ["connect_time"]=> float(0.05576)
  ["pretransfer_time"]=> float(0.055878)
  ["size_upload"]=> float(0)
  ["size_download"]=> float(0)
  ["speed_download"]=> float(0)
  ["speed_upload"]=> float(0)
  ["download_content_length"]=> float(371712)
  ["upload_content_length"]=> float(0)
  ["starttransfer_time"]=> float(0.100382)
  ["redirect_time"]=> float(0)
  ["redirect_url"]=> string(0) ""
  ["primary_ip"]=> string(11) "XXX"
  ["certinfo"]=> array(0) { }
  ["primary_port"]=> int(80)
  ["local_ip"]=> string(11) "XXX"
  ["local_port"]=> int(XX)
}

如果我将本地文件的时间戳更改为小于远程文件的时间戳2014-12-06 06:56:03,这些是信息

array(26) {
  ["url"]=> string(32) "XXX"
  ["content_type"]=> string(24) "application/octet-stream"
  ["http_code"]=> int(200)
  ["header_size"]=> int(251)
  ["request_size"]=> int(113)
  ["filetime"]=> int(1418014742)
  ["ssl_verify_result"]=> int(0)
  ["redirect_count"]=> int(0)
  ["total_time"]=> float(0.583712)
  ["namelookup_time"]=> float(0.011975)
  ["connect_time"]=> float(0.056813)
  ["pretransfer_time"]=> float(0.056977)
  ["size_upload"]=> float(0)
  ["size_download"]=> float(371712)
  ["speed_download"]=> float(636807)
  ["speed_upload"]=> float(0)
  ["download_content_length"]=> float(371712)
  ["upload_content_length"]=> float(0)
  ["starttransfer_time"]=> float(0.103772)
  ["redirect_time"]=> float(0)
  ["redirect_url"]=> string(0) ""
  ["primary_ip"]=> string(11) "XXX"
  ["certinfo"]=> array(0) { }
  ["primary_port"]=> int(80)
  ["local_ip"]=> string(11) "XX"
  ["local_port"]=> int(XX)
}

如您所见,两者之间存在差异,[size download],第一个为 =0,第二个为 >0。

有什么建议吗?我总是会得到一个 http 代码 = 200?

---------编辑

这是我返回的带有本地时间戳 2014-12-08 06:59:01 的标头

HTTP/1.1 200 OK Server: nginx Date: Mon, 08 Dec 2014 10:23:06 GMT Content-Type: application/octet-stream Content-Length: 371712 Last-Modified: Mon, 08 Dec 2014 04:59:02 GMT Connection: keep-alive ETag: "54853016-5ac00" Accept-Ranges: bytes

【问题讨论】:

    标签: php http curl


    【解决方案1】:

    是的,你误解了文档。

    如果尚未修改,则假定 CURLOPT_HEADER 为 TRUE,将返回“304 Not Modified”标头。

    无变化 -> 返回“304 Not Modified”标头。

    修改 -> 返回 200

    ---------第2轮---------

    文件的最后修改时间:格林威治标准时间 2014 年 12 月 18 日星期四 05:37:48。

    date_default_timezone_set("Etc/GMT");
    $url = "...";
    $timestamp = "2014-12-18 05:37:48";
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_TIMEVALUE, strtotime($timestamp));
    curl_setopt($ch, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
    $res = curl_exec($ch);
    

    1,如果我使用上面的测试代码,它会返回这样的头部:

    HTTP/1.1 304 Not Modified
    Date: Thu, 18 Dec 2014 08:27:55 GMT
    Server: Apache/2.4.7 (Ubuntu)
    ETag: "17c-50a76fe108d7a"
    

    2,当我更改 $timestamp 时,它会返回:

    HTTP/1.1 200 OK
    Date: Thu, 18 Dec 2014 08:31:02 GMT
    Server: Apache/2.4.7 (Ubuntu)
    Last-Modified: Thu, 18 Dec 2014 05:37:48 GMT
    ETag: "17c-50a76fe108d7a"
    Accept-Ranges: bytes
    Content-Length: 380
    Vary: Accept-Encoding
    Content-Type: text/html
    

    我认为你应该设置时区,如果我不设置时区,它总是返回 200。

    【讨论】:

    • 感谢您的回复,但这很奇怪,因为使用 CURLOPT_TIMECONDITION 仅当资源自 CURLOPT_TIMEVALUE 中的时间戳以来未被修改时才获取正文,但 http 代码将始终为 200 - 如果自从我的时间戳以来,资源还没有被修改过?在什么情况下我会得到 304?如果我查询一年前修改过的文件2013-12-22 04:59:00 我仍然得到 200。
    • 我发现了问题。你应该设置时区。 -- date_default_timezone_set("Etc/GMT");
    猜你喜欢
    • 1970-01-01
    • 2017-10-30
    • 2012-08-14
    • 1970-01-01
    • 2015-05-09
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-05-26
    相关资源
    最近更新 更多