7

我需要获取远程文件的内容,但要发送一些标头,其中一个是“连接:保持活动”标头...所以我通过简单调用 file_get_contents() 来尝试它,就像这样:

<?php

$sfheaders="Cache-Control:max-age=0
Connection:keep-alive";

$opts = array(
    'http' => array(
        'method' => "GET",
        'header' => $sfheaders
    )
);

$context = stream_context_create($opts);

$url="http://somedomain.com/to.php";
$file = file_get_contents($url, false, $context);
?>

...代码有效,但 file_get_contents 需要 15 秒才能获取数据!看起来 file_get_contents() 在连接关闭后完成,但我希望它在数据传输后完成。如果我删除 keep-alive 标头会更快,但这次我需要在连接保持活动状态时获取数据。我猜这对于 file_get_contents 是不可能的,所以....

有没有办法用 cURL 或其他东西来做到这一点?

编辑:让我更准确地说,必须将“Connection:keep-alive”标头发送到我尝试访问的特定服务器,因为它会检查该标头,如果未发送,则没有数据发送到我!知道了?

4

1 回答 1

5

保持连接

通常,如果连接未设置为keep-alive,则一旦 PHP 终止当前脚本,剩余的输出缓冲区将被转发到 Web 服务器,Web 服务器又将数据转发到客户端。然后网络服务器关闭它与客户端(浏览器)的连接。

如果您要求

Connection: keep-alive

服务器就是这样做的:它保持连接打开,即使回复已经完全完成。因此,上述行为很好。此外,例如feof()不会返回 FALSE - 因为最终可能会到达更多数据。

请注意,您可以在当前运行的 PHP 脚本中重新使用 keep-alive 连接。但是一旦你的 PHP 脚本完成,keep-alive 连接就会断开。

因此,您不能使用下一个 PHP 脚本实例重用保持活动连接。

案例 1 - 请求前已知的数据量

如果您事先知道数据量,则可能只读取该数据量$expectedAmountOfDataInBytes然后关闭连接:

$expectedAmountOfDataInBytes = 2023;

$handle = fopen( "http://www.stackoverflow.com/", "r" );

if ( ! is_resource( $handle )) {
    echo 'sorry';
    exit;
}

while(  ( ! feof( $handle ) )
     && ( 0 < $expectedAmountOfDataInBytes-- )
     ) {

    $contents .= fread( $handle, 1 );

}

fclose($handle);

案例 2 - 请求前未知的数据量

如果事先不知道数据量,需要提交HTTP请求

GET /infotext.html HTTP/1.1
Host: www.example.net

并解析这样的答案:

HTTP/1.1 200 OK
Server: Apache/1.3.29 (Unix) PHP/4.3.4
Content-Length: 4 
Content-Language: de (nach RFC 3282 sowie RFC 1766)
Connection: close
Content-Type: text/html

ABCD

PHP 手册中找到一个基于套接字 I/O的简单 HTTP 客户端。

于 2013-08-12T21:52:53.673 回答