Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

file_get_contents returns empty string

Tags:

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

like image 529
Your Common Sense Avatar asked Nov 13 '10 14:11

Your Common Sense


People also ask

What will the file_get_contents () return?

The function returns the read data or false on failure. This function may return Boolean false , but may also return a non-Boolean value which evaluates to false .

What is the function file_get_contents () useful for?

The file_get_contents() reads a file into a string. This function is the preferred way to read the contents of a file into a string.

What is the difference between file_get_contents () function and file () function?

The file_get_contents() function reads entire file into a string. The file() function reads the entire file in a array, whereas file_get_contents() function reads the entire file into a string.

Does file_get_contents cache?

Short answer: No. file_get_contents is basically just a shortcut for fopen, fread, fclose etc - so I imagine opening a file pointer and freading it isn't cached.


2 Answers

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.

like image 114
Eric Caron Avatar answered Oct 10 '22 05:10

Eric Caron


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.

like image 32
mario Avatar answered Oct 10 '22 05:10

mario