php file_get_contents 返回空字符串

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4172860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 12:12:28  来源:igfitidea点击:

file_get_contents returns empty string

phpfopen

提问by Your Common Sense

I am hesitated to ask this question because it looks weird. But anyway. Just in case someone had encountered the same problem already... filesystem functions (fopem, file, file_get_contents) behave very strange for http:// wrapper

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

  • it seemingly works. no errors raised. fopen() returns resource.
  • it returns no data for all certainly working urls (e.g. http://google.com/).
    file returns empty array, file_get_contents() returns empty string, fread returns false
  • for all intentionally wrong urls (e.g. http://goog973jd23le.com/) it behaves exactly the same, save for little [supposedly domain lookup] timeout, after which I get no error (while should!) but empty string.
  • url_fopen_wrapper is turned on
  • curl (both command line and php versions) works fine, all other utilities and applications works fine, local files opened fine
  • 它似乎有效。没有错误提出。fopen() 返回资源。
  • 对于所有肯定有效的 url(例如http://google.com/),它不返回任何数据。
    file 返回空数组,file_get_contents() 返回空字符串,fread 返回 false
  • 对于所有故意错误的 url(例如http://goog973jd23le.com/),它的行为完全相同,除了很少的 [supposely domain lookup] 超时,之后我没有错误(虽然应该!)但空字符串。
  • url_fopen_wrapper 已开启
  • curl(命令行和 php 版本)工作正常,所有其他实用程序和应用程序工作正常,本地文件打开正常

This errorseems inapplicable because in my case it doesn't work for every url or host.

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

php-fpm 5.2.11 Linux version 2.6.35.6-48.fc14.i686 ([email protected])

php-fpm 5.2.11 Linux 版本 2.6.35.6-48.fc14.i686 ([email protected])

回答by Eric Caron

I fixed this issue on my server (running PHP 5.3.3 on Fedora 14) by removing the --with-curlwrapper from the PHP configuration and rebuilding it.

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

回答by mario

Sounds like a bug. But just for posterity, here are a few things you might want to debug.

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

  • allow_url_fopen: already tested
  • PHP under Apache might behave differently than PHP-CLI, and would hint at chroot/selinux/fastcgi/etc. security restrictions
  • local firewall: unlikely since curl works
  • user-agent blocking: this is quite common actually, websites block crawlers and unknown clients
  • transparent proxy from your ISP, which either mangles or blocks (PHP user-agent or non-user-agent could be interpreted as malware)
  • PHP stream wrapper problems
  • allow_url_fopen: 已经测试过了
  • PHP 在 Apache 下的行为可能与 PHP-CLI 不同,并且会提示 chroot/selinux/fastcgi/etc。安全限制
  • 本地防火墙:不太可能,因为 curl 有效
  • 用户代理阻止:这实际上很常见,网站会阻止爬虫和未知客户端
  • 来自 ISP 的透明代理,它会破坏或阻止(PHP 用户代理或非用户代理可能被解释为恶意软件)
  • PHP流包装器问题

Anyway, first let's proof that PHPs stream handlers are functional:

不管怎样,首先让我们证明 PHP 的流处理程序是有效的:

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

Then try to see if PHP makes real HTTP requests at all. First open netcat on the console:

然后尝试查看 PHP 是否发出真正的 HTTP 请求。首先在控制台打开netcat:

nc -l 80000

And debug with just:

并调试:

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

And from here you can try to communicate with PHP, see if anything returns if you variate the response. Enter an invalid response first into netcat. If there's no error thrown, your PHP package is borked.

从这里你可以尝试与 PHP 通信,看看如果你改变响应是否有任何返回。首先在 netcat 中输入无效响应。如果没有抛出错误,那么您的 PHP 包就被破坏了。

(You might also try communicating over a "tcp://.." handle then.)

(您也可以尝试通过“tcp://..”句柄进行通信。)

Next up is experimenting with http stream wrapper parameters. Use http://example.com/literally, which is known to work and never block user-agents.

接下来是试验 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);

I think ignore_errorsis very relevant here. But check out http://www.php.net/manual/en/context.http.phpand specifically try to set protocol_versionto 1.1 (will get chunked and misinterpreted response, but at least we'll see if anythingreturns).

我认为ignore_errors在这里非常相关。但是请查看http://www.php.net/manual/en/context.http.php并特别尝试设置protocol_version为 1.1(会得到分块和误解的响应,但至少我们会看到是否有任何返回)。

If even this remains unsuccessful, then try to hack the http wrapper.

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

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

This will not only set the User-Agent, but inject extra headers. If there is a processing issue with construction the request within the http stream wrapper, then this could very eventually catch it.

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

Otherwise try to disable any Zend extensions, Suhosin, PHP xdebug, APC and other core modules. There could be interferences. Else this is potentiallyan issue specific to the Fedora package. Try a new version, see if it persists on your system.

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

回答by Jeremy

When you use the http stream wrapper PHP creates an array for you called $http_response_headerafter file_get_contents()(or any of the other f family of functions) is called. This contains useful info on the state of the response. Could you do a var_dump()of this array and see if it gives you any more info on the response?

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

It's a really weird error that you're getting. The only thing I can think of is that something else on the server is blocking the http requests from PHP, but then I can't see why cURL would still be ok...

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

回答by Donatas Olsevi?ius

Is http stream registered in your PHP installation? Look for "Registered PHP Streams" in your phpinfo()output. Mine says "https, ftps, compress.zlib, compress.bzip2, php, file, glob, data, http, ftp, phar, zip".

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

If there is no http, set allow_url_fopento on in your php.ini.

如果没有http,请allow_url_fopen在您的php.ini.

回答by c0rnh0li0

What does a test with fsockopentell you?

fsockopen的测试告诉你什么?

Is the test isolated from other code?

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

回答by Master Drools

I had the same issue in Windows after installing XAMPP 1.7.7. Eventually I managed to solve it by adding the following line to php.ini (while having allow_url_fopen = On):

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

extension=php_openssl.dll

扩展=php_openssl.dll