views:

384

answers:

4

I've been having some issues with my Internet connection and I was wondering what is the fastest, error-less and most reliable way to check if the host computer is connected to the Internet.

I'm looking for something like is_online() that returns true when online and false when not.

+1  A: 

You could send a ping to a host that is probably up (e.g. Google).

There seems to be no PHP built-in for this, so you'd have to resort to shell commands. The return value of ping on *nix can tell you whether a reply was received.

Update: ping -c1 -q -w1 should be the right command on Linux. This will give you exit code 0 if a reply was received, something else otherwise, and it times out after one second.

Hence, something like this (warning, my PHP is rusty) should do the trick:

function is_online() {
    $retval = 0;
    system("ping -c1 -q -w1", $retval);
    return $retval == 0;
}
Thomas
Alix Axel
+1  A: 

Why don't you do a number of HTTP GET (or better still HTTP HEAD for speed) requests on popular web sites? Use majority voting to decide on the answer.

You can sometimes rely on ping too (through a system call in PHP) but note that not all web sites respond to ICMP (ping) requests.

Note that by increasing the number of ping/http requests you make before drawing a conclusion helps with the confidence level of the answer but can't be error free in the worst of cases.

jldupont
Thanks I was thinking in the same lines as you, do you happen to know how to make HEAD requests with file_get_contents() and stream_context_create()? I'm asking this because I don't wanna rely just on CURL to make the request.
Alix Axel
my php is a bit rusty.
jldupont
$context = stream_context_create(array('http' => array('method' => 'HEAD'))); $response = file_get_contents($url, null, $context); $response will be false (===) on failure. The returned headers will be stored in $http_response_header.
GZipp
I've benchmarked it and quering google.com takes more than 1 second per request, check my answer for a follow up.
Alix Axel
A: 

Don't forget this assumes that your server will respond to ICMP requests. If that's the case then I agree, Net_Ping is probably the way to go. Failing that you could use the Net_Socket package, also on PEAR, to attempt a connection to some port that you know will get a response from - perhaps port 7 or port 80 depending on what services you have running.

kguest
A: 

I've benchmarked some solutions: file_get_contents with HEAD request, gethostbynamel, checkdnsrr and the following solution seems to be more than 100 faster than all the others:

function is_online()
{
    return (checkdnsrr('google.com', 'ANY') && checkdnsrr('yahoo.com', 'ANY') && checkdnsrr('microsoft.com', 'ANY'));
}

Takes about one microsecond per each host, while file_get_contents for instance takes more than one second per each host (when offline).

Alix Axel