2013-03-29 60 views
0

我繼承了一段代碼,它使用下面的fetchURL()函數從url中獲取數據。我剛剛注意到,在檢索整頁數據之前,它通常會返回feof()。我已經嘗試過一些測試,並且使用file_get_contents()CURL每次都檢索完整頁面。帶有套接字的feof()的假eof fgets

錯誤是間歇性的。 在9個調用中,有時7個會成功完成,有時只有4個。9箇中的特定4個(它們只是獲取請求,只是查詢字符串不斷變化)總是成功完成。我已經嘗試顛倒請求的順序,並且相同的4個查詢字符串仍然總是成功,而其餘的有時不工作。
因此,「似乎」返回的數據可能與這個問題有關,但是這是間歇性的,讓我變得狡猾。在每種情況下返回的數據總是相同的(因爲每次我用?SearchString=8502806的查詢字符串進行調用時,返回的頁面都包含相同的數據),但有時整個頁面由fgets/feof提供,有時不提供。

有沒有人有什麼可能會導致這種情況的建議? O在這個問題上看到的大多數其他帖子都是關於feof()沒有返回true的相反問題。

function fetchURL($url, $ret = 'body') { 
    $url_parsed = parse_url($url); 
    $host = $url_parsed["host"]; 
    $port = (isset($url_parsed["port"]))?$url_parsed["port"]:''; 
    if ($port==0) 
     $port = 80; 
    $path = $url_parsed["path"]; 
    if ($url_parsed["query"] != "") 
     $path .= "?".$url_parsed["query"]; 

    $out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n"; 

    $fp = fsockopen($host, $port, $errno, $errstr, 30); 

    fwrite($fp, $out); 
    $body = false; 
    $h = ''; 
    $b = ''; 
    while (!feof($fp)) { 
     $s = fgets($fp, 1024); 
     if ($body) 
      $b .= $s; 
     else 
      $h .= $s; 
     if ($s == "\r\n") 
      $body = true; 
    } 

    fclose($fp); 

    return ($ret == 'body')?$b:(($ret == 'head')?$h:array($h, $b)); 
} 
+0

套接字上的'feof'通常(總是?)是一個壞主意,因爲它會在繼續之前等待服務器實際關閉套接字。至少你應該發送'Connection:close'頭文件,但是我會認真地推薦完全重寫這段代碼,因爲它很糟糕(沒有任何意圖)。 –

+0

我計劃轉換爲CURL,但我想知道什麼可能會導致我看到的問題。因此,這個問題。 –

回答

-1

這聽起來像是超時問題。請參閱PHP手冊中的stream_set_timeout()

+0

超時與例外情況類似,如果事情出錯,應該使用它們來捕獲錯誤,但不能用於正常使用。 –

+0

@從互聯網獲取數據時,@TomvanderWoerdt超時是不可避免的。這是對不可預知行爲的合理解釋,不是嗎? – grahamj42

+0

是的,超時是不可避免的,但根據他沒有超時的問題來判斷。絕對不是所有請求的20%。 –

2

我發現該代碼有很多錯誤。

  • 永遠不要在插座上使用feof。它將掛起,直到服務器關閉套接字,在收到頁面後不一定立即發生。
  • feof可能會返回true(套接字已關閉),而PHP的緩衝區中仍有一些數據。
  • 你的代碼區分標題和身體似乎依賴於PHP做它的工作正常,這通常是一個壞主意。 fgets不一定看一條線,它也可以只返回一個字節(\r,則下一次調用你可能會得到\n
  • 你沒有正確編碼路徑值

何不你只是將你的代碼轉換爲使用cURL或file_get_contents?

+0

我正在計劃轉換爲CURL,但我想知道什麼可能會導致我看到的問題。因此,這個問題。 –