file_get_contents返回空字符串

时间:2010-11-13 14:00:35

标签: php fopen

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

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

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

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

7 个答案:

答案 0 :(得分:23)

我通过从PHP配置中删除--with-curlwrapper并重建它来修复我的服务器上的问题(在Fedora 14上运行PHP 5.3.3)。

答案 1 :(得分:14)

听起来像个臭虫。但是对于后代来说,这里有一些你可能想要调试的东西。

  • allow_url_fopen:已经过测试
  • Apache下的PHP可能与PHP-CLI的行为不同,并暗示chroot / selinux / fastcgi / etc。安全限制
  • 本地防火墙:自卷曲起作用不太可能
  • 用户代理阻止:实际上这很常见,网站会阻止抓取工具和未知客户端
  • 来自您的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包特有的问题。尝试新版本,看看它是否仍存在于您的系统中。

答案 2 :(得分:4)

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

这是一个非常奇怪的错误,你得到了。我唯一能想到的是服务器上的其他东西阻止了来自PHP的http请求,但后来我无法理解为什么cURL仍然可以......

答案 3 :(得分:2)

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

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

答案 4 :(得分:-1)

使用fsockopen的测试告诉您什么?

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

答案 5 :(得分:-1)

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

延长= php_openssl.dll

答案 6 :(得分:-3)