Search code examples
phpjsonfile-get-contents

For some reason file_get_contents stopped working from one day to another and returns a "HTTP/1.1 406 Not Acceptable" error in PHP 7.2.34


THE PROBLEM

I am mantaining a webpage that's running in a server hosted by Inmotion and using PHP 7.2.34. Let's call it "https://company-website.net/"

Inside this page we need to read a JSON file. The file for sure is there, one can go to the url and open it and the JSON file is located in "https://company-website.net/locale.json"

And from one day to another, on January 10th 2024, file_get_contents suddenly returned this php error:

file_get_contents(https://company-website.net/locale.json): failed to open stream: HTTP request failed! HTTP/1.1 406 Not Acceptable

The code looked like this:

$fileUrl = 'https://'.$_SERVER['SERVER_NAME'].'/locale.json';
$file = file_get_contents($fileUrl);

I tried something else

I tried setting an Accept header like it said on this stack overflow thread (just changed Accept-Language: en for Accept: /: PHP file_get_contents() and setting request headers

So, the code ended like this:

$fileUrl = 'https://'.$_SERVER['SERVER_NAME'].'/locale.json';
$opts = [
    "http" => [
        "method" => "GET",
        "header" => "Accept: */*"
    ]
];
$context = stream_context_create($opts);
$file = file_get_contents($fileUrl, false, $context);

But nothing

THE SOLUTION IN THE END

Then I ended up changing file get contents for curl, as mentioned in this thread: PHP file_get_contents() returns "failed to open stream: HTTP request failed!"

so it ended up like this:

$fileUrl = 'https://'.$_SERVER['SERVER_NAME'].'/locale.json';
$curl_handle=curl_init();
curl_setopt($curl_handle, CURLOPT_URL, $fileUrl);
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, 'Company Name');
$file = curl_exec($curl_handle);
curl_close($curl_handle);

AND IT WORKED.

But still I'm baffled as to WHY it stopped working form one day to the other, not sure if it has something to do with PHP deprecation, with Inmotion changing something security wise, really lost here. I still want to try and use file_get_contents and understand what the issue could be. If anyone can give any insight, I'd be more than thankful.


Solution

  • using PHP 7.2.34

    The biggest difference between file_get_contents and curl in PHP 7 is that file_get_contents defaults to using http/1.0, while curl uses http/1.1. Based on the returned 406 error, I believe it is highly likely that this is the reason. (Don't feel strange, even if your request is sent with http/1.0, the server can response an http/1.1 error, see this question)

    Additionally, your curl code has added UA, which may be another issue.

    Try to add these two items to the context:

    "protocol_version" => "1.1"
    "user_agent" => "Company Name"