7

リモートファイルの内容を取得する必要がありますが、いくつかのヘッダーを送信し、そのうちの1つは「接続:キープアライブ」ヘッダーです...そのため、このように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-alivePHP が現在のスクリプトを終了すると、残りの出力バッファーが Web サーバーに転送され、Web サーバーがデータをクライアントに転送します。次に、Web サーバーはクライアント (ブラウザー) への接続を閉じます。

リクエストする場合

Connection: keep-alive

サーバーはまさにこれを行います。応答が完全に終了した場合でも、接続を開いたままにします。したがって、前述の動作は問題ありません。さらに、egfeof()は FALSE を返しません。最終的にさらに多くのデータが到着する可能性があるためです。

現在実行中の PHP スクリプト内でキープアライブ接続を再利用できることに注意してください。ただし、PHP スクリプトが終了すると、キープアライブ接続は切断されます。

したがって、次の 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 に答える