2010-11-13 242 views
17

我很猶豫要問這個問題,因爲它看起來很奇怪。 但無論如何。 萬一有人已經遇到了同樣的問題... 文件系統函數(fopem,文件的file_get_contents)表現爲HTTP很奇怪://封裝file_get_contents返回空字符串

  • 它似乎工作。 沒有錯誤提出。 fopen()返回資源。
  • 它不會爲所有工作的網址(例如http://google.com/)返回任何數據。
    文件返回空數組,file_get_contents()函數返回空字符串,FREAD返回false
  • 所有故意錯誤的URL(如http://goog973jd23le.com/)它的行爲完全一樣,除小[理應域名查詢]超時,在這之後我沒有得到任何錯誤(而應該!),但空字符串。
  • url_fopen_wrapper被打開
  • 捲曲(包括命令行和PHP版本)正常工作,所有其他的工具和應用程序運行正常,本地文件打開的細

This error似乎不適用,因爲在我的情況下,不適用於每個網址或主機。

PHP-FPM 5.2.11 Linux版本的2.6.35.6-48.fc14.i686([email protected]

+0

有什麼理由,爲什麼你不希望使用的libcurl?似乎如果這是工作,它可能是一個理想的替代品。 – Treffynnon 2010-11-13 14:11:16

+1

@Treffynnon我正在重寫代碼以使用現在的curl,但仍想知道file_get_contents()的最新錯誤 – 2010-11-13 14:19:46

+0

對於哪個特定的URL不起作用? – mario 2010-11-13 14:21:08

回答

22

我通過從PHP配置中刪除--with-curlwrapper並重建它來解決了我的服務器上的這個問題(在Fedora 14上運行PHP 5.3.3)。

+1

今天再次被跳過,這次default_socket_timeout設置爲0(這應該意味着無限制)導致它立即失敗。 – 2012-07-09 17:31:24

+0

保存我的一天,非常有幫助!謝謝@Eric Caron – 2013-09-06 15:20:15

4

當您使用HTTP流包裝PHP創建一個數組因爲file_get_contents()(或任何其他f系列函數)之後調用$http_response_header。這包含有關響應狀態的有用信息。你可以做一個var_dump()這個數組,看看它是否給你任何更多的答覆信息?

這是一個非常奇怪的錯誤,你會得到。我能想到的唯一的事情是服務器上的其他東西阻止了來自PHP的http請求,但是我不明白爲什麼cURL仍然會好起來......

+0

http_header_response上的var_dump給出一個NULL值。 – 2010-12-09 01:57:47

+0

你的意思是$ http_response_header,對吧? – Jeremy 2010-12-12 04:42:42

2

HTTP流是否在您的PHP安裝中註冊?在您的phpinfo()輸出中查找「Registered PHP Streams」。我說「https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, zip」。

如果沒有http,請在您的php.ini中將allow_url_fopen設置爲打開。

12

聽起來像一個錯誤。但只是爲了後人,這裏有一些你可能想要調試的東西。

  • allow_url_fopen:已經測試過Apache下
  • PHP的行爲可能不同於PHP-CLI,並會在chroot/SELinux的/ FastCGI的/等提示。安全限制
  • 本地防火牆:不可能的,因爲捲曲的作品
  • 用戶代理阻止:這是相當普遍實際上,網站攔截檢索和未知的客戶
  • 從你的ISP,這無論是軋液或者塊(PHP用戶
  • 透明代理劑或非用戶代理可以被解釋爲惡意軟件)
  • PHP流包裝問題

無論如何,首先讓我們來證明PHP的流處理器是功能:

<?php 
    if (!file_get_contents("data:,ok")) { 
      die("Houston, we have a stream wrapper problem."); 
    } 

然後嘗試查看PHP是否發出真正的HTTP請求。首先打開的netcat在控制檯上:

nc -l 80000 

和調試只用:

<?php 
    print file_get_contents("http://localhost:8000/hello"); 

,從這裏,你可以嘗試用PHP進行溝通,看看是否有什麼,如果你的變動內容響應返回。首先輸入一個無效的響應到netcat中。如果沒有錯誤發生,您的PHP軟件包就會被凍結。

(您也可以嘗試溝通過「TCP:// ..」處理即可。)

接下來與HTTP流包裝參數的試驗。字面上使用http://example.com/,這是已知的工作,並永遠不會阻止用戶代理。

$context = stream_context_create(array("http"=>array(
    "method" => "GET", 
    "header" => "Accept: xml/*, text/*, */*\r\n", 
    "ignore_errors" => false, 
    "timeout" => 50, 
)); 

print file_get_contents("http://www.example.com/", false, $context, 0, 1000); 

我覺得ignore_errors是非常相關的。但檢查出http://www.php.net/manual/en/context.http.php,並特別嘗試將protocol_version設置爲1.1(將得到分塊和曲解的響應,但至少我們會看到是否返回任何東西)。

如果即使這仍然不成功,然後嘗試破解http包裝。

<?php 
    ini_set("user_agent" , "Mozilla/3.0\r\nAccept: */*\r\nX-Padding: Foo"); 

這不僅會設置User-Agent,還會注入額外的標頭。如果在http流包裝器中構造請求時存在處理問題,那麼這可能最終會抓住它。

否則嘗試禁用任何Zend擴展,Suhosin,PHP xdebug,APC和其他核心模塊。可能會有干擾。否則這是Fedora軟件包特有的潛在問題。嘗試一個新版本,看看它是否存在於你的系統上。

-1

安裝XAMPP 1.7.7後,我在Windows中遇到了同樣的問題。最後,我設法將下面的行爲php.ini來解決這個問題(同時具有了allow_url_fopen = ON):

延長= php_openssl.dll