15
$url = 'http://a.url/i-know-is-down';

//ini_set('default_socket_timeout', 5);

$ctx = stream_context_create(array(
    'http' => array(
        'timeout' => 5,
        'ignore_errors' => true
        )
    )
);

$start = microtime(true);
$content = @file_get_contents($url, false, $ctx);
$end = microtime(true);
echo $end - $start, "\n";

the response I get is generally 21.232 segs, shouldn't be about five seconds???

Uncommenting the ini_set line don't help at all.

Cesar
  • 4,076
  • 8
  • 44
  • 68
  • Could you try turning off both the "ignore_errors" flag as well as the silent @file_get_contents() call and see if any obvious errors pop out? – Mahdi.Montgomery Sep 11 '10 at 02:03
  • @Mahdi.M: I can not turn off `ingnore_errors` because I need to distinguish between say a 404 error and an error generated by connectivity problems. Let me rephrase it. If ingnore_errors` is off and the server return a 404 $content would be false and i need to know if $content if false because a 404 error or beacuse a connectivity error. The error showed when I suppress the @ operator is a generic one like `file_get_contents(filename): failed to open stream` – Cesar Sep 15 '10 at 07:18
  • 2
    As a rule of thumb, you shouldn't ever need to use @. If it's critical to your application, you are likely writing it in the wrong way. Not always, but pretty damn often! – Rich Bradshaw May 12 '12 at 08:46
  • @Cesar: if you need to distinguish HTTP Error codes, read `$http_response_header` after calling `file_get_contents()`. It gets populated as an array of the HTTP Headers returned by the server. You can get all errors except server connection problems (server not found, timeout, connection refused, etc) – MestreLion Dec 19 '18 at 12:00

1 Answers1

15

You are setting the read timeout with socket_create_context. If the page you are trying to access doesn't exist then the server will let you connect and give you a 404. However, if the site doesn't exist (won't resolve or no web server behind it), then file_get_contents() will ignore read timeout because it hasn't even timed out connecting to it yet.

I don't think you can set the connection timeout in file_get_contents. I recently rewrote some code to use fsockopen() exactly because it lets you specify connect timeout

$connTimeout = 30 ;
$fp = fsockopen($hostname, $port, $errno, $errstr, $connTimeout);

Ofcourse going to fsockopen will require you to then fread() from it in a loop, compicating your code slightly. It does give you more control, however, on detecting read timeouts while reading from it using stream_get_meta_data()

http://php.net/stream_get_meta_data

Fanis Hatzidakis
  • 5,282
  • 1
  • 33
  • 36