file_get_contents 返回空字符串

发布于 2024-10-01 18:04:39 字数 879 浏览 1 评论 0原文

我很犹豫要不要问这个问题,因为它看起来很奇怪。 但无论如何。 以防万一有人遇到过同样的问题...... 文件系统函数(fopem、file、file_get_contents)对于 http:// 包装器来说表现得很奇怪,

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

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

PHP-FPM 5.2.11 Linux 版本 2.6.35.6-48.fc14.i686 ([电子邮件受保护]

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

  • 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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

憧憬巴黎街头的黎明 2024-10-08 18:04:39

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

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.

﹎☆浅夏丿初晴 2024-10-08 18:04:39

听起来像是一个错误。但仅供参考,以下是您可能需要调试的一些内容。

  • 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

并使用 just 进行调试:

<?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");

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

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

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

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

<?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:

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.

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

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

$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_errors is very relevant here. But check out http://www.php.net/manual/en/context.http.php and specifically try to set protocol_version to 1.1 (will get chunked and misinterpreted response, but at least we'll see if anything returns).

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

<?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.

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.

人│生佛魔见 2024-10-08 18:04:39

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

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

When you use the http stream wrapper PHP creates an array for you called $http_response_header after 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?

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...

镜花水月 2024-10-08 18:04:39

您的 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 设置为 on。

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".

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

北风几吹夏 2024-10-08 18:04:39

我的问题在处理 SSL 时得到解决:

$arrContextOptions = array(
  "ssl" => array(
    "verify_peer" => false,
    "verify_peer_name" => false,
  ),
);  

$context = stream_context_create($arrContextOptions);
        
$jsonContent = file_get_contents("https://www.yoursite.com", false, $context);

My problem was solved dealing with the SSL:

$arrContextOptions = array(
  "ssl" => array(
    "verify_peer" => false,
    "verify_peer_name" => false,
  ),
);  

$context = stream_context_create($arrContextOptions);
        
$jsonContent = file_get_contents("https://www.yoursite.com", false, $context);
苦笑流年记忆 2024-10-08 18:04:39

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

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

What does a test with fsockopen tell you?

Is the test isolated from other code?

执妄 2024-10-08 18:04:39

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

extension=php_openssl.dll

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):

extension=php_openssl.dll

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文