371

I wrote a PHP code like this

$site="http://www.google.com";
$content = file_get_content($site);
echo $content;

But when I remove "http://" from $site I get the following warning:

Warning: file_get_contents(www.google.com) [function.file-get-contents]: failed to open stream:

I tried try and catch but it didn't work.

5

17 Answers 17

592

Step 1: check the return code: if($content === FALSE) { // handle error here... }

Step 2: suppress the warning by putting an error control operator (i.e. @) in front of the call to file_get_contents(): $content = @file_get_contents($site);

10
  • 103
    Remember to use strict comparison: if ($content === FALSE) .If the file contains "0", then it will trigger a false negative. Jun 24, 2011 at 3:48
  • 8
    Hi, this didn't work for me, adding @ still causes E_WARNING to be caught by some global (not mine) error handler, and my script dies before I have a chance to handle the return value. Any ideas? tnx.
    – Sagi Mann
    Nov 22, 2012 at 6:51
  • 2
    Side effect detected: if the file does not exist, the script stops at the @file_get_contents line.
    – Dax
    Dec 23, 2012 at 13:42
  • 5
    Though the answer is very old, I still suggest adding a note to your answer that using @ may negatively impact performance. See this answer on a related post that explains fairly well.
    – Fr0zenFyr
    Jun 30, 2015 at 19:35
  • 5
    don't do this. You just surpress the error warning. this is no error handling! this will make problems in debugging.
    – helle
    Jul 15, 2019 at 8:56
180

You can also set your error handler as an anonymous function that calls an Exception and use a try / catch on that exception.

set_error_handler(
    function ($severity, $message, $file, $line) {
        throw new ErrorException($message, $severity, $severity, $file, $line);
    }
);

try {
    file_get_contents('www.google.com');
}
catch (Exception $e) {
    echo $e->getMessage();
}

restore_error_handler();

Seems like a lot of code to catch one little error, but if you're using exceptions throughout your app, you would only need to do this once, way at the top (in an included config file, for instance), and it will convert all your errors to Exceptions throughout.

10
  • @enobrev, Why do you put the same value for both error number and severity?
    – Pacerier
    Jul 16, 2013 at 18:38
  • No specific reason besides a means of offering something useful in $exception->getCode(), since set_error_handler does not offer an error number variable (unfortunately).
    – enobrev
    Jul 16, 2013 at 19:42
  • 2
    @lolka_bolka because file_get_contents doesn't throw an exception, but instead throws a php error. So what this example does is sets up an "error handler" that catches most instances of php errors being thrown and instead converts those errors to exceptions. Here's a more modern example from the docs: php.net/manual/en/…
    – enobrev
    Oct 1, 2015 at 17:23
  • 2
    @enobrev Don't forget to restore error handler inside anonymous function before throwing exception. Exception can be handled and in that case the handler is still set to throw this particular exception which may come as unexpected and introduce weird, hard to debug, behavior when there is another error in exception handling. Oct 23, 2017 at 8:57
  • 2
    I would recommend to include restore_error_handler() call in finally block
    – peschanko
    Apr 7, 2019 at 10:00
117

My favorite way to do this is fairly simple:

if (($data = @file_get_contents("http://www.google.com")) === false) {
      $error = error_get_last();
      echo "HTTP request failed. Error was: " . $error['message'];
} else {
      echo "Everything went better than expected";
}

I found this after experimenting with the try/catch from @enobrev above, but this allows for less lengthy (and IMO, more readable) code. We simply use error_get_last to get the text of the last error, and file_get_contents returns false on failure, so a simple "if" can catch that.

6
  • 2
    This is the easiest and best solution for this problem! Maybe make it @file_get_contents to supress the error reporting to the browser.
    – EDP
    Dec 30, 2015 at 8:36
  • 1
    I admit that among all the answers this is the only sensible one -- if we'd augment it to use @file_get_contents to suppress the warning and test the result value using === FALSE.
    – kostix
    Feb 10, 2016 at 13:01
  • 13
    This will trigger errors for successful requests that don't return a body, or return one that evaluates to false. Should be if (false !== ($data = file_get_contents ()))
    – GordonM
    Jun 6, 2016 at 9:49
  • 3
    The first condition is backwards. If false does not equal the result of the file_get_contents call then it got some contents and we should not be looking for an error. I was confused in seeing errors from the previous test or seeing an error that $error was null when google really was found!
    – Robert
    Jan 23, 2021 at 17:15
  • 1
    I have updated the answer to include the feedback in prior comments. Aug 17, 2021 at 2:05
42

You can prepend an @: $content = @file_get_contents($site);

This will supress any warning - use sparingly!. See Error Control Operators

Edit: When you remove the 'http://' you're no longer looking for a web page, but a file on your disk called "www.google....."

1
  • That's the only thing that really works - I could not suppress the "failed to open stream" message any other way.
    – Olaf
    Sep 25, 2017 at 13:06
26

One alternative is to suppress the error and also throw an exception which you can catch later. This is especially useful if there are multiple calls to file_get_contents() in your code, since you don't need to suppress and handle all of them manually. Instead, several calls can be made to this function in a single try/catch block.

// Returns the contents of a file
function file_contents($path) {
    $str = @file_get_contents($path);
    if ($str === FALSE) {
        throw new Exception("Cannot access '$path' to read contents.");
    } else {
        return $str;
    }
}

// Example
try {
    file_contents("a");
    file_contents("b");
    file_contents("c");
} catch (Exception $e) {
    // Deal with it.
    echo "Error: " , $e->getMessage();
}
19
function custom_file_get_contents($url) {
    
    return file_get_contents(
        $url,
        false,
        stream_context_create(
            array(
                'http' => array(
                    'ignore_errors' => true
                )
            )
        )
    );
}


if( $content = custom_file_get_contents($url) ) {

    //play with the result

} 
else {

    //handle the error
}
4
  • This doesn't work. If the $url is 404 not found, warning will still appear.
    – Raptor
    May 16, 2014 at 3:16
  • Right Raptor, I have improved the answer with stream_context_create(); Nothing better... "@" not recommended
    – RafaSashi
    May 16, 2014 at 14:23
  • 1
    ignore_errors only instructs the HTTP context to not interpret HTTP response status codes >= 400 as errors. While marginally related, that does not answer the question of PHP error handling.
    – sun
    Jul 1, 2014 at 16:51
  • 1
    Thanks for ignore_errors option! This is what I needed!
    – Modder
    Feb 16, 2020 at 17:25
16

Here's how I did it... No need for try-catch block... The best solution is always the simplest... Enjoy!

$content = @file_get_contents("http://www.google.com");
if (strpos($http_response_header[0], "200")) { 
   echo "SUCCESS";
} else { 
   echo "FAILED";
} 
2
  • 5
    -1: this works if you get a 404 error or something, but not if you fail to connect to the server at all (e.g. wrong domain name). I think $http_response_header is not updated in that case, since no HTTP response is received. Mar 24, 2013 at 1:50
  • 1
    As @NathanReed said, you should check $content is not false (with ===) as that's what gets return if the request fails to connect at all
    – Seb
    Jan 20, 2014 at 9:25
7

Here's how I handle that:

$this->response_body = @file_get_contents($this->url, false, $context);
if ($this->response_body === false) {
    $error = error_get_last();
    $error = explode(': ', $error['message']);
    $error = trim($error[2]) . PHP_EOL;
    fprintf(STDERR, 'Error: '. $error);
    die();
}
5

The best thing would be to set your own error and exception handlers which will do something usefull like logging it in a file or emailing critical ones. http://www.php.net/set_error_handler

0

Since PHP 4 use error_reporting():

$site="http://www.google.com";
$old_error_reporting = error_reporting(E_ALL ^ E_WARNING);
$content = file_get_content($site);
error_reporting($old_error_reporting);
if ($content === FALSE) {
    echo "Error getting '$site'";
} else {
    echo $content;
}
-1

something like this:

public function get($curl,$options){
    $context = stream_context_create($options);
    $file = @file_get_contents($curl, false, $context);
    $str1=$str2=$status=null;
    sscanf($http_response_header[0] ,'%s %d %s', $str1,$status, $str2);
    if($status==200)
        return $file        
    else 
        throw new \Exception($http_response_header[0]);
}
-2

You could use this script

$url = @file_get_contents("http://www.itreb.info");
if ($url) {
    // if url is true execute this 
    echo $url;
} else {
    // if not exceute this 
    echo "connection error";
}
1
  • This needs strict comparison: if ($url === true)... because if you get as a response 0 or empty, it raises connection error.
    – Daniel W.
    Mar 13, 2018 at 13:00
-2

You should use file_exists() function before to use file_get_contents(). With this way you'll avoid the php warning.

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}
1
  • 2
    This would only work, if you call a local file and you have the right permissions to check the local file if it exists
    – rubo77
    Jan 30, 2018 at 11:05
-2

Simplest way to do this is just prepend an @ before file_get_contents, i. e.:

$content = @file_get_contents($site); 
-2

I was resolve all problem, it's work all links

public function getTitle($url)
    {
        try {
            if (strpos($url, 'www.youtube.com/watch') !== false) {
                $apikey = 'AIzaSyCPeA3MlMPeT1CU18NHfJawWAx18VoowOY';
                $videoId = explode('&', explode("=", $url)[1])[0];
                $url = 'https://www.googleapis.com/youtube/v3/videos?id=' . $videoId . '&key=' . $apikey . '&part=snippet';

                $ch = curl_init();

                curl_setopt($ch, CURLOPT_HEADER, 0);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
                curl_setopt($ch, CURLOPT_VERBOSE, 0);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                $response = curl_exec($ch);
                curl_close($ch);

                $data = json_decode($response);
                $value = json_decode(json_encode($data), true);

                $title = $value['items'][0]['snippet']['title'];
            } else {
                set_error_handler(
                    function () {
                            return false;
                    }
                );
                if (($str = file_get_contents($url)) === false) {
                    $title = $url;
                } else {
                    preg_match("/\<title\>(.*)\<\/title\>/i", $str, $title);
                    $title = $title[1];
                    if (preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $title))
                        $title = utf8_encode($title);
                    $title = html_entity_decode($title);
                }
                restore_error_handler();
            }
        } catch (Exception $e) {
            $title = $url;
        }
        return $title;
    }
1
  • 1
    Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Oct 9, 2021 at 9:31
-4

This will try to get the data, if it does not work, it will catch the error and allow you to do anything you need within the catch.

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}
0
-5
if (!file_get_contents($data)) {
  exit('<h1>ERROR MESSAGE</h1>');
} else {
      return file_get_contents($data);
}
2
  • 1
    no. you should you === for condition checking. not == Nov 7, 2020 at 10:37
  • 3
    Wouldn't recommend running file_get_contents twice. Once is enough.
    – Juakali92
    Jan 30, 2021 at 20:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.