2009-07-24 11 views
1

ソケットを使用してWebサイトを取得するときに、この異常な動作が発生します。以下のget_content()関数から返される文字列には、元のWebサイトには存在しない「追加情報」が含まれています。ソケットを使用したときの異常な動作

function get_content($a, $b, $c = "00") 
{ 
    $request = "arg01=" . $a; 
    $request .= "&arg02=" . $b; 
    $request .= "&arg03=" . $c; 

    $host = "www.site.com"; 
    $script = "/page.php"; 
    $method = "POST"; 

    $request_length = strlen($request); 

    $header = "$method $script HTTP/1.1\r\n"; 
    $header .= "Host: $host\r\n"; 
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; 
    $header .= "Content-Length: $request_length\r\n"; 
    $header .= "Connection: close\r\n\r\n"; 
    $header .= "$request\r\n"; 

    $socket = @fsockopen($host, 80, $errno, $errstr); 
    if ($socket) { 
     fputs($socket, $header); 
      while(!feof($socket)) { 
       $output .= fgets($socket); 
      } 
     fclose($socket); 
    } 

    return $output; 
} 

印刷$出力:ブロックの下

HTTP/1.1 200 OK 
Date: Fri, 24 Jul 2009 15:20:38 GMT 
Server: Apache/2.2.8 (Unix) PHP/4.4.8 
X-Powered-By: PHP/4.4.8 
Connection: close 
Transfer-Encoding: chunked 
Content-Type: text/html 

1f61 
<html> 
<head> 
    <title> 

    (...) html here (...) 
      <td align='right'><font size='-1'> 18,65</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 24,10</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 18,40</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 24,10</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 24,10</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 18,65</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 
f43 
    24,10</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 18,65</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 18,65</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 24,10</font></td> 
    (...) html here (...) 
      <td align='right'><font size='-1'> 18,40</font></td> 

    (...) html here (...) 
    </body> 
</html> 

0 

注:これは、元のHTML上に存在しない

  <td align='right'><font size='-1'> 
f43 
    24,10</font></td> 

  <td align='right'><font size='-1'> 24,10</font></td> 

他のタグと同じように。

この問題を解決するために、ソケットをカールに置き換えました。

function get_content($a, $b, $c = "00") 
{ 
    $args = "arg01=" . $a; 
    $args .= "&arg02=" . $b; 
    $args .= "&arg03=" . $c; 

    $host = "http://www.site.com/page.php"; 

    $ch = curl_init($host); 
    curl_setopt($ch, CURLOPT_URL, $host); 
    curl_setopt($ch, CURLOPT_POST, count($args)); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, $args); 
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
    curl_exec($ch); 
    $output = curl_multi_getcontent($ch); 
    curl_close($ch); 

    return $output; 
} 

CURLは問題を解決しますが、ここで何が起こっているのかを理解したいと思います。この「追加情報」の原点は何ですか?ワームホールなどから?

あなたは考えがありますか?

ありがとうございます!

答えて

5

あなたが転送チャンクモードでデータ(このヘッダがあるので、あなたはこれをチェックすることができます

Transfer-encoding: chunked 

を)からコンテンツを取得するサーバー。

チャンク転送符号化は、次のように動作します。サーバーは、次のチャンクの長さを表す16進数(ASCII文字)を送信します。それから、CRLF(\ r \ n)を送り、次にチャンクを送り、次にCRLFをもう一度送ります。例:

10 
1234567890abcdef 
0C 
qwertyuiopas 

CURLは、これを処理しますが、rawソケットのデータを読んでいるので、それはあなたが取得しているコンテンツに表示されます。

元のHTMLにはなかった追加の "f43"は、実際には次のチャンク(3907バイト)の長さです。

とにかく、CURLや他のHTTPライブラリを使用することをお勧めします.HMTLのチャンク転送コードなどのすべてのサブタイトルのプロトコルを実装すると、多くの作業が必要になります。基本的なプロトコルハンドラは、1つの基本的なケースでのみ動作します。

+0

最近のPHP(5.2.9、IIRC)のアップグレードでは、fpassthru()がチャンクされたデータを処理しなくなり、ブラウザに長さが渡される問題が発生しました。私はfpassthru()を避け、それぞれのチャンクをエコーする前に自分自身で応答をdechunkしなければならなかった。 – grantwparks

関連する問題