17

Why am I getting this error?

Warning: file_get_contents(http://www.example.com) [function.file-get-contents]: failed to open stream: HTTP request failed! in C:\xampp\htdocs\test.php on line 22

Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\test.php on line 22

Here is the code:

 try {
    $sgs = file_get_contents("http://www.example.com");
 }
 catch (Exception $e) {
    echo '123';
 }
 echo '467';

Aren't try\catch supposed to continue the excecution of the code? Or maybe there is some different way to do it?

Victor Marchuk
  • 13,045
  • 12
  • 43
  • 67
  • 4
    Because [file_get_contents()](http://www.php.net/file_get_contents) doesn't throw an exception. It triggers an error. – Charles Sprayberry Jul 31 '11 at 17:14
  • [can-i-try-catch-a-warning](https://stackoverflow.com/questions/1241728/can-i-try-catch-a-warning) solves your question. –  Sep 17 '18 at 21:25

7 Answers7

19

try... catch is more for null object exceptions and manually thrown exceptions. It really isn't the same paradigm as you might see in Java. Warnings are almost deceptive in the fact that they will specifically ignore try...catch blocks.

To suppress a warning, prefix the method call (or array access) with an @.

 $a = array();
 $b = @$a[ 1 ]; // array key does not exist, but there is no error.

 $foo = @file_get_contents( "http://somewhere.com" );
 if( FALSE === $foo ){ 
     // you may want to read on === there;s a lot to cover here. 
     // read has failed.
 }

Oh, and it is best to view Fatal Exceptions are also completely uncatchable. Some of them can be caught in some circumstances, but really, you want to fix fatal errors, you don't want to handle them.

cwallenpoole
  • 79,954
  • 26
  • 128
  • 166
  • Hm, not so very good advice. Usage of the error suppressor should be avoided. Instead log warnings and make sure you're not getting them by properly validating with `isset()` or in the other example determine that the target exists and try more than once. – markus Oct 14 '13 at 20:39
  • @markus While that is good as a general rule, sometimes it is far better to use a warning-suppressed function than it is to log warnings. – cwallenpoole Oct 14 '13 at 21:09
  • @markus Case in point, AFAIK the only way to get check `file_get_contents` over HTTP is to use `file_exists` (which means you are hitting the remote server twice) or cURL, which is a great deal more expensive in terms of developer overhead. – cwallenpoole Oct 14 '13 at 21:12
  • @markus The long and the short is that you should only be using the suppression syntax if you are specifically trying to suppress an error. – cwallenpoole Oct 14 '13 at 21:13
  • 1
    In the first example, there's no excuse :-). In the second example, if it's just software for personal use, no problem. Otherwise check at least the response code first, if you don't want to curl, `get_headers` will do the trick, no need for file_exists and much less expensive. After fetching the headers, `substr($headers[0], 9, 3)` will return the three digit response code. – markus Oct 14 '13 at 21:40
  • When I use the '@' prefix, I can avoid the failure, but how on earth can I know the reason of the failure? There really isn't java like try-catch paradigm in PHP, where we know what failed and what have to be fixed ? – Tomas Bartalos Oct 18 '17 at 12:20
  • @TomasBartalos Because it's always been that way? Realistically, if you're using `@`, you're suppressing one set of knowable warnings. If you're in a fatal exception, well, it's fatal. The process, it is. There's nothing left able to catch. – cwallenpoole Oct 18 '17 at 13:50
6

catch cannot catch a fatal error.

Just search for timeout in the manual for file_get_contents, there are several solutions listed there, here is one:

$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 1
        )
    )
);
file_get_contents("http://example.com/", 0, $ctx); 
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
4

try..catch will only catch exceptions. A fatal error is not an exception.

If PHP exceeds its maximum execution time, there's nothing you can do. PHP simply stops dead. It's the same if PHP runs out of memory: Nothing you can do to fix it after it's happened.

In other words, exceptions are errors you can potentially recover from. Fatal errors are, well, fatal and unrecoverable.

Flambino
  • 18,507
  • 2
  • 39
  • 58
2

In PHP a fatal error will halt execution of the script. There are ways to do something when you run into them, but the idea of a fatal error is that it should not be caught.

Community
  • 1
  • 1
karim79
  • 339,989
  • 67
  • 413
  • 406
2

Here are some good details: http://pc-technic.blogspot.com/2010/10/php-filegetcontents-exception-handling.html

Basically change your code to do the following:

try {
    @$sgs = file_get_contents("http://www.example.com"); 
    if ($sgs == FALSE)
    {
       // throw the exception or just deal with it
    }
} catch (Exception $e) {
    echo '123'; 
}
 echo '467';

Note the use of the '@' symbol. This tells PHP to ignore errors raised by that particular piece of code. Exception handling in PHP is very different than java/c# due to the "after the fact" nature of it.

NotMe
  • 87,343
  • 27
  • 171
  • 245
1

Fatal errors in PHP are not caught. Error handling and Exception handling are two different things. However if you are hell bent on handling fatal errors as exception, you will need to set up your own error handler and direct all errors to it, make your error handler throw exceptions and you can then catch them.

Kumar
  • 5,038
  • 7
  • 39
  • 51
1

file_get_contents doesn't throw exception (and thus errors and warnings it throws aren't catchable). You are getting PHP warning and then fatal error, which explains you why the script doesn't continue - it exceeded limit for loading scripts set in php.ini.

Ondrej Slinták
  • 31,386
  • 20
  • 94
  • 126