php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61336 file_get_contents() no longer returns false on 4xx responses
Submitted: 2012-03-09 21:59 UTC Modified: 2016-05-06 14:06 UTC
Votes:7
Avg. Score:3.7 ± 0.7
Reproduced:5 of 6 (83.3%)
Same Version:3 (60.0%)
Same OS:2 (40.0%)
From: ramsey@php.net Assigned:
Status: Wont fix Package: Filesystem function related
PHP Version: 5.4.0 OS: CentOS 6.2
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2012-03-09 21:59 UTC] ramsey@php.net
Description:
------------
In PHP 5.3, file_get_contents() returns false on 4xx responses. In PHP 5.4, 
file_get_contents() is returning the actual response body, rather than false.

Test script:
---------------
<?php

$response = file_get_contents('http://us3.php.net/manual/en/function.foobar.php');

var_dump($http_response_header);
var_dump($response);

Expected result:
----------------
With warnings turned on, this is what I get in PHP 5.3 and what I expect to see 
in PHP 5.4:

PHP Warning:  
file_get_contents(http://us3.php.net/manual/en/function.foobar.php): failed to 
open stream: HTTP request failed! HTTP/1.0 404 Not Found
 in /Users/ramsey/Desktop/file_get_contents.php on line 3
PHP Stack trace:
PHP   1. {main}() /Users/ramsey/Desktop/file_get_contents.php:0
PHP   2. file_get_contents() /Users/ramsey/Desktop/file_get_contents.php:3
array(11) {
  [0]=>
  string(22) "HTTP/1.0 404 Not Found"
  [1]=>
  string(35) "Date: Fri, 09 Mar 2012 21:57:32 GMT"
  [2]=>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3]=>
  string(23) "X-Powered-By: PHP/5.3.2"
  [4]=>
  string(20) "Content-language: en"
  [5]=>
  string(88) "Set-Cookie: LAST_LANG=en; expires=Sat, 09-Mar-2013 21:57:32 GMT; 
path=/; domain=.php.net"
  [6]=>
  string(102) "Set-Cookie: COUNTRY=USA%2C64.2.187.194; expires=Fri, 16-Mar-2012 
21:57:32 GMT; path=/; domain=.php.net"
  [7]=>
  string(21) "Status: 404 Not Found"
  [8]=>
  string(20) "Content-Length: 4219"
  [9]=>
  string(17) "Connection: close"
  [10]=>
  string(37) "Content-Type: text/html;charset=utf-8"
}
bool(false)

Actual result:
--------------
array(11) {
  [0]=>
  string(22) "HTTP/1.1 404 Not Found"
  [1]=>
  string(35) "Date: Fri, 09 Mar 2012 21:58:44 GMT"
  [2]=>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3]=>
  string(23) "X-Powered-By: PHP/5.3.2"
  [4]=>
  string(20) "Content-language: en"
  [5]=>
  string(88) "Set-Cookie: LAST_LANG=en; expires=Sat, 09-Mar-2013 21:58:44 GMT; 
path=/; domain=.php.net"
  [6]=>
  string(102) "Set-Cookie: COUNTRY=USA%2C64.2.187.194; expires=Fri, 16-Mar-2012 
21:58:44 GMT; path=/; domain=.php.net"
  [7]=>
  string(21) "Status: 404 Not Found"
  [8]=>
  string(20) "Content-Length: 4219"
  [9]=>
  string(17) "Connection: close"
  [10]=>
  string(37) "Content-Type: text/html;charset=utf-8"
}
string(4219) "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
                      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <title>PHP: 404 Not Found</title>
 <style type="text/css" media="all">
  @import url("/styles/site.css");
  @import url("/styles/mirror.css");

...

The rest of the HTML output from the php.net 404 page.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-03-09 22:41 UTC] seld@php.net
Just for the record, repro script works for me on Windows / 5.4.0 VC9 NTS
 [2012-03-10 14:21 UTC] cataphract@php.net
-Status: Open +Status: Feedback
 [2012-03-10 14:21 UTC] cataphract@php.net
I can't reproduce this. Probably the default context has ignore_errors on. Verify that it doesn't and try to pass a context that has ignore_errors set to false.
 [2012-03-13 15:20 UTC] ramsey@php.net
I'm still seeing the problem with ignore_errors set to false. See below for how 
I'm setting ignore_errors. For full details on how my environment is set up, you 
can refer to http://benramsey.com/blog/2012/03/build-php-54-on-centos-62/.


<?php

$context = stream_context_create(array(
    'http' => array(
        'ignore_errors' => false
    )
));

$response = 
file_get_contents('http://us3.php.net/manual/en/function.foobar.php', false, 
$context);

var_dump($http_response_header);
var_dump($response);
 [2012-03-13 20:24 UTC] ramsey@php.net
I've just tried this on a clean Debian 6.0.4 virtual machine, and I'm having the 
same problem there (I've tried even with ignore_errors set to false).

Here are the PHP build notes for my Debian installation: http://pastie.org/3588244
 [2012-03-28 21:59 UTC] ramsey@php.net
-Status: Feedback +Status: Open
 [2012-03-29 22:42 UTC] ramsey@php.net
On that same Debian 6.0.4 VM (using VirtualBox), I built PHP from the latest checkout of the PHP-5.4 branch. `php --version` gives me the following version line: PHP 5.4.1RC1-dev (cli) (built: Mar 29 2012 18:34:37)

When I run my test script with this build of PHP, I am still having the same problem.
 [2012-03-29 23:19 UTC] ramsey@php.net
I've just checked out the PHP-5.3 branch on the same environments and built it with exactly the same config values as my 5.4 builds. `php --version` shows me this: PHP 5.3.11-dev (cli) (built: Mar 29 2012 19:12:58)

It appears that I'm having the exact same problem with the latest checkout from PHP 5.3 in these same two environments (Debian 6.0.4 and CentOS 6.2). Either I have a problem in both of these environments, or the code that is broken in 5.4 has recently been merged to 5.3. Unfortunately, others that I have asked to test this cannot reproduce it in their environments, so that points to a problem with my environment. Any help identifying that problem is greatly appreciated. I have posted detailed instructions on exactly what I have done to set up each environment.
 [2012-03-30 06:29 UTC] ramsey@php.net
I've just done a clean install of Ubuntu 11.10 on VirtualBox and then built PHP 5.4 from the PHP-5.4 branch. I am still encountering this problem.

As this point, the single commonality between environments is that I'm using VirtualBox. Could this problem be a result of the way in which VirtualBox accesses the network?
 [2012-03-30 16:39 UTC] rasmus@php.net
Unable to reproduce this on any of my Ubuntu 11.10 or Centos machines. I have 
Centos in a VM, but not Virtualbox.

Perhaps you have some weird proxying going on? Break out tcpdump and see what is 
actually coming across the wire.
 [2012-10-18 15:43 UTC] stasismedia at gmail dot com
I actually get the same issue on both 5.3.11 and 5.4.4:

5.3.11:
-------

array(11) {
  [0]=>
  string(22) "HTTP/1.1 404 Not Found"
  [1]=>
  string(35) "Date: Thu, 18 Oct 2012 15:35:04 GMT"
  [2]=>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3]=>
  string(23) "X-Powered-By: PHP/5.3.2"
  [4]=>
  string(20) "Content-language: en"
  [5]=>
  string(88) "Set-Cookie: LAST_LANG=en; expires=Fri, 18-Oct-2013 15:35:04 GMT; 
path=/; domain=.php.net"
  [6]=>
  string(101) "Set-Cookie: COUNTRY=GBR%2C94.195.8.27; expires=Thu, 25-Oct-2012 
15:35:04 GMT; path=/; domain=.php.net"
  [7]=>
  string(21) "Status: 404 Not Found"
  [8]=>
  string(20) "Content-Length: 4182"
  [9]=>
  string(17) "Connection: close"
  [10]=>
  string(37) "Content-Type: text/html;charset=utf-8"
}
string(4182) "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"


5.4.4:
-------

array(11) {
  [0] =>
  string(22) "HTTP/1.1 404 Not Found"
  [1] =>
  string(35) "Date: Thu, 18 Oct 2012 15:35:19 GMT"
  [2] =>
  string(29) "Server: Apache/2.2.3 (CentOS)"
  [3] =>
  string(23) "X-Powered-By: PHP/5.3.2"
  [4] =>
  string(20) "Content-language: en"
  [5] =>
  string(88) "Set-Cookie: LAST_LANG=en; expires=Fri, 18-Oct-2013 15:35:19 GMT; 
path=/; domain=.php.net"
  [6] =>
  string(101) "Set-Cookie: COUNTRY=GBR%2C94.195.8.27; expires=Thu, 25-Oct-2012 
15:35:19 GMT; path=/; domain=.php.net"
  [7] =>
  string(21) "Status: 404 Not Found"
  [8] =>
  string(20) "Content-Length: 4182"
  [9] =>
  string(17) "Connection: close"
  [10] =>
  string(37) "Content-Type: text/html;charset=utf-8"
}
string(4182) "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"\n
 [2012-10-18 15:51 UTC] stasismedia at gmail dot com
I should add...

Both PHP versions in Ubuntu 12.04 x64 running as a guest in Virtualbox.
 [2013-01-14 23:52 UTC] vestigalorgan at gmail dot com
I'm experiencing a similar issue in the PHP version 5.4.7 that ships with XAMPP. When I open a web URL that throws a warning such as "Warning: file_get_contents(http://[ip_address_here]:[port_here]): failed to open stream: No connection could be made because the target machine actively refused it.", file_get_contents() returns an empty string, instead of false.

I'm not sure if this is related to this bug or I should file a new one. I'm experiencing this on Windows 7 Professional, SP1 32-bit. I'm only using the first parameter of file_get_contents().
 [2013-03-01 09:54 UTC] php at maisqi dot com
I think I have new info on this issue. If you check the URI at the bottom you'll find three tests:

1. Using file_file_get_contents() on an non-existing resource on a existing domain:
     Result                : empty string
     $http_response_header : an array

2. Using file_file_get_contents() on a non-existing domain, with follow_location => 0 on the context:
     Result                : empty string
     $http_response_header : NULL

3. Using file_file_get_contents() on a non-existing domain, __without__ follow_location => 0 on the context:
     Result                : non empty string
     $http_response_header : an array

I'd expect that all the results should be NULL.

I think the problem has to to with idiosyncratic behavior on some internal library. In the third test we can see that there's something asking OpenDNS when trying to deal with the non-existing behavior; and then it sends a Location header. This behavior is not documented.

- The same script on a Windows 7/Apache Server [PHP 5.4.12] works as expected;
- On a Debian 3.2.35-2 running PHP 5.2.5 it works as expected;
- On a Turnkey Linux (Ubuntu based Linux) running PHP 5.3.3-7+squeeze14 it works as expected;
- On a Ubuntu running PHP 5.3.3-7+squeeze14 it works as expected.

So I'd say it has to do with the underlying system libraries and configuration; it would be nice if others test the script on other kind of servers...

Test script: http://maisqi/outros/bugs/php/61336
[CentOS / PHP 5.4.11]
 [2013-03-02 01:50 UTC] vestigalorgan at gmail dot com
I've run the test case that maisqi provided, and here are my results:


1. Using file_file_get_contents() on an non-existing resource on a existing domain:
    The result: boolean
    $http_response_header: array

2. Using file_file_get_contents() on a non-existing domain, with follow_location => 0 on the context:
    The result: boolean
    $http_response_header: NULL

3. Using file_file_get_contents() on a non-existing domain, __without__ follow_location => 0 on the context:
    The result: boolean
    $http_response_header: NULL

This is on Ubuntu 12.04 LTS 64-bit with Apache 2.2.22 and PHP 5.3.10-1ubuntu3.5 with the Suhosin-Patch. Everything appears to be working fine there.

Shouldn't the output of the results be a boolean false, not NULL, maisqi?
 [2013-03-04 15:01 UTC] php at maisqi dot com
vestigalorgan, you are right: it should return false in all three cases. Thanks for correcting.
 [2013-03-04 15:04 UTC] php at maisqi dot com
Just noted that I gave a wrong URI to the script; sorry, here is the right one:

http://maisqi.com/outros/bugs/php/61336
 [2013-03-29 20:19 UTC] stasismedia at gmail dot com
FYI, I experienced this issue when PHP was compiled with --with-curlwrappers
 [2013-03-30 13:29 UTC] laruence@php.net
confirm, when compile with curlwrappers, 
then I am not sure whether this is a bug, since curlwrappers has it's own 
implementation..
 [2016-05-06 14:06 UTC] nikic@php.net
-Status: Open +Status: Wont fix
 [2016-05-06 14:06 UTC] nikic@php.net
Closing this as "Won't Fix" as --with-curlwrappers has been removed inf PHP 5.5, so this is no longer relevant.
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Nov 19 01:31:42 2017 UTC