file_get_contents 返回空字符串

Posted

技术标签:

【中文标题】file_get_contents 返回空字符串【英文标题】:file_get_contents returns empty string 【发布时间】:2011-05-09 12:59:54 【问题描述】:

我不敢问这个问题,因为它看起来很奇怪。 但无论如何。 以防万一有人已经遇到同样的问题...... 文件系统函数(fopem、file、file_get_contents)对于 http:// wrapper 的行为非常奇怪

它似乎有效。 没有出现错误。 fopen() 返回资源。 它不返回所有确实有效的网址的数据(例如http://google.com/)。 file 返回空数组,file_get_contents() 返回空字符串,fread 返回 false 对于所有故意错误的 url(例如http://goog973jd23le.com/),它的行为完全相同,除了 [supposedly domain lookup] 超时,之后我没有收到错误(虽然应该!)但是空字符串。 url_fopen_wrapper 已开启 curl(命令行和 php 版本)工作正常,所有其他实用程序和应用程序工作正常,本地文件打开正常

This error 似乎不适用,因为在我的情况下,它不适用于每个 url 或主机。

php-fpm 5.2.11 Linux 版本 2.6.35.6-48.fc14.i686 (mockbuild@x86-18.phx2.fedoraproject.org)

【问题讨论】:

有什么理由不想使用 libcurl 吗?似乎这是否有效,它可能是您的理想替代品。 @Treffynnon 我现在正在重写代码以使用 curl,但仍然想知道 file_get_contents() 有什么问题 对哪个特定的 URL 不起作用? @Col。弹片 是的,这是一种奇怪的东西,我以前从未遇到过。当您也发现时,我期待看到正在发生的事情。 我猜是因为http://google.com/ 重定向到http://www.google.com 你尝试过其他网址吗? 【参考方案1】:

我通过从 PHP 配置中删除 --with-curlwrapper 并重建它,在我的服务器上解决了这个问题(在 Fedora 14 上运行 PHP 5.3.3)。

【讨论】:

今天又被这个绊倒了,这次将 default_socket_timeout 设置为 0(这应该意味着无限)导致它立即失败。【参考方案2】:

听起来像一个错误。但为了后代,这里有一些你可能想要调试的东西。

allow_url_fopen:已经测试过了 Apache 下的 PHP 可能与 PHP-CLI 不同,并且会提示 chroot/selinux/fastcgi/etc。安全限制 本地防火墙:不太可能,因为 curl 有效 用户代理拦截:这其实很常见,网站拦截爬虫和未知客户端 来自您的 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 包是 borked。

(您也可以尝试通过“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(会得到分块和误解的响应,但至少我们会看看 anything 是否返回)。

如果这仍然不成功,请尝试破解 http 包装器。

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

这不仅会设置 User-Agent,还会注入额外的标头。如果在 http 流包装器中构造请求时存在处理问题,那么这最终可能会捕获它。

否则尝试禁用任何 Zend 扩展、Suhosin、PHP xdebug、APC 和其他核心模块。可能会有干扰。否则,这可能是 Fedora 软件包特有的问题。尝试新版本,看看它是否仍然存在于您的系统中。

【讨论】:

***.com/questions/2226374/… 将完成这个惊人的指南 allow_url_fopen 已关闭并导致问题。【参考方案3】:

当您使用 http 流包装器时,PHP 在调用 file_get_contents()(或任何其他 f 系列函数)后为您创建一个名为 $http_response_header 的数组。这包含有关响应状态的有用信息。您能否对此数组进行var_dump() 并查看它是否为您提供了有关响应的更多信息?

这是您遇到的一个非常奇怪的错误。我唯一能想到的是服务器上的其他东西正在阻止来自 PHP 的 http 请求,但是我不明白为什么 cURL 仍然可以......

【讨论】:

http_header_response 上的 var_dump 给出 NULL。【参考方案4】:

您的 PHP 安装中是否注册了 http 流?在phpinfo() 输出中查找“Registered PHP Streams”。我说“https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, zip”。

如果没有http,请在php.ini 中将allow_url_fopen 设置为开启。

【讨论】:

【参考方案5】:

fsockopen 的测试告诉你什么?

测试是否与其他代码隔离?

【讨论】:

【参考方案6】:

安装 XAMPP 1.7.7 后,我在 Windows 中遇到了同样的问题。最终我设法通过将以下行添加到 php.ini 来解决它(同时让 allow_url_fopen = On):

extension=php_openssl.dll

【讨论】:

【参考方案7】:

使用http://pear.php.net/reference/PHP_Compat-latest/__filesource/fsource_PHP_Compat__PHP_Compat-1.6.0a2CompatFunctionfile_get_contents.php.html并重命名它并测试这个重写的函数是否发生错误。

【讨论】:

以上是关于file_get_contents 返回空字符串的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 file_get_contents(),不返回任何内容

readfile & file_get_contents异同

PHP file_get_contents() 返回“打开流失败:HTTP 请求失败!”

使用 file_get_contents 将本地 PHP 文件的 HTML 输出存储到字符串中

php fopen与file_get_contents的区别

file_get_contents() 分解 UTF-8 字符