1

If i run this code in PHP with a wrong proxy I get 500 internal server error. How to handle it and continue execution?

$opts = array(
          'http'=>array(
            'method'=>"GET",
            'proxy' => 'tcp://100.100.100.100:80' //a wrong proxy
          )
);

$context = stream_context_create($opts);

$file = file_get_contents('http://ifconfig.me/ip', false, $context);
pnuts
  • 58,317
  • 11
  • 87
  • 139
Davide
  • 1,635
  • 1
  • 16
  • 29

1 Answers1

3

I assume you mean two things when you say “handle”:

  1. If the script connects to a “wrong” proxy, it will wait for a long time to establish the connection, until it times out. The script should set a lower timeout, so users don't wait forever.
  2. If an error occures during accessing the external ressource, don't die or show ugly messages. Instead, pretend everything's cool.

As for 1) The timeout of a remote connection is defined in PHP's default_socket_timeout setting and is by default 60 seconds. You can/should set a much lower timeout for your own calls:

$opts = array(
      'http'=>array(
        'timeout'=> 2, // timeout of 2 seconds
        'proxy' => 'tcp://100.100.100.100:80' //a wrong proxy
      )
);

As for 2), you would normally use a try/catch block. Unfortunately, file_get_contents() is one of those old PHP functions that don't throw catchable exceptions.

You can supress a possible error message by prefixing the function call with the @ sign:

$file = @file_get_contents('http://ifconfig.me/ip', false, $context);

But then you can't handle any errors at all.

If you want to have at least some error handling, you should use cURL. Unfortunately, it also doesn't throw exceptions. However, if a cURL error occurs, you can read it with curl_errno()/curl_error().

Here's your code implemented with cURL:

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, "http://ifconfig.me/ip");
curl_setopt($ch, CURLOPT_PROXY, 'tcp://100.100.100.100:80');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
curl_setopt($ch, CURLOPT_HEADER, 1);

$data = curl_exec($ch);
$error = curl_errno($ch) ? curl_error($ch) : '';

curl_close($ch);

print_r($error ? $error : $data);

This way, you can decide what you want to do in the case of an error.

lxg
  • 12,375
  • 12
  • 51
  • 73
  • This cURL approach will show cURL errors, like error `58`, `CURLE_SSL_CERTPROBLEM`. It will not handle HTTP 500 errors. For those, check out this answer: http://stackoverflow.com/a/408416/1487413. Also, this code sticks the HTTP headers onto the data for some reason, using `CURLOPT_HEADER`. This isn't very handy. Per the cURL manual "it is not possible to accurately separate them again without detailed knowledge about the protocol in use." – Martin Burch Mar 31 '15 at 16:28