Determine in php script if connected to internet?
Asked Answered
D

14

53

How can I check if I'm connected to the internet from my PHP script which is running on my dev machine?

I run the script to download a set of files (which may or may not exist) using wget. If I try the download without being connected, wget proceeds to the next one thinking the file is not present.

Damaris answered 1/2, 2011 at 8:29 Comment(0)
P
95
<?php
function is_connected()
{
    $connected = @fsockopen("www.example.com", 80); 
                                        //website, port  (try 80 or 443)
    if ($connected){
        $is_conn = true; //action when connected
        fclose($connected);
    }else{
        $is_conn = false; //action in connection failure
    }
    return $is_conn;

}
?>
Patronymic answered 1/2, 2011 at 8:37 Comment(2)
+ Nice answer be someone else might think [80|443] would switch between any of the ports ... :)Septime
Based on this post, it would probably make a lot of sense to use example.com as the "www.some_domain.com" of the answer.Justinjustina
B
10

You can always ping good 'ol trusty google:

$response = null;
system("ping -c 1 google.com", $response);
if($response == 0)
{
    // this means you are connected
}
Bigname answered 1/2, 2011 at 8:37 Comment(2)
This is quite reliable, but keep in mind that "ICMP works != TCP works" (what with firewalls, NATs and whatnot), and even "TCP works != HTTP works" (transparent proxies etc.).Derosier
Anyway to mute messages? I get "Ping request could not find google.com. Please check the name and try again." echoed to the page when there is no connection. Accurate, of course, but not what I want a user to see. ;) @system does not suppress the messages.Disfigurement
H
9

This code was failing in laravel 4.2 php framework with an internal server 500 error:

<?php
     function is_connected()
     {
       $connected = @fsockopen("www.some_domain.com", 80); 
        //website, port  (try 80 or 443)
       if ($connected){
          $is_conn = true; //action when connected
          fclose($connected);
       }else{
         $is_conn = false; //action in connection failure
       }
      return $is_conn;
    }
?>

Which I didn't want to stress myself to figure that out, hence I tried this code and it worked for me:

function is_connected()
{
  $connected = fopen("http://www.google.com:80/","r");
  if($connected)
  {
     return true;
  } else {
   return false;
  }

} 

Please note that: This is based upon the assumption that the connection to google.com is less prone to failure.

Hanforrd answered 16/1, 2015 at 20:8 Comment(2)
Nice alternative! This also requires allow_url_fopen = On in php.iniWeakling
In my tests fopen is twice slower than the fsockopen alternative. Also, it would look nicer this syntax instead of an ugly if() with return true/false: return (bool) fopen("google.com:80/","r");Hubing
N
5

The accepted answer did not work for me. When the internet was disconnected it threw a php error. So I used it with a little modification which is below:

if(!$sock = @fsockopen('www.google.com', 80))
{
    echo 'Not Connected';
}
else
{
echo 'Connected';
}
Niddering answered 17/2, 2016 at 23:1 Comment(0)
A
3

Why don't you fetch the return code from wget to determine whether or not the download was successful? The list of possible values can be found at wget exit status.

On the other hand, you could use php's curl functions as well, then you can do all error tracking from within PHP.

Ancestry answered 1/2, 2011 at 8:44 Comment(0)
V
1

There are various factors that determine internet connection. The interface state, for example. But, regardles of those, due to the nature of the net, proper configuration does not meen you have a working connection.

So the best way is to try to download a file that you’re certain that exists. If you succeed, you may follow to next steps. If not, retry once and then fail.

Try to pick one at the destination host. If it’s not possible, choose some major website like google or yahoo.

Finally, just try checking the error code returned by wget. I bet those are different for 404-s and timeouts. You can use third parameter in exec call:

string exec ( string $command [, array &$output [, int &$return_var ]] )

Vanda answered 1/2, 2011 at 8:38 Comment(0)
S
1
/*
 * Usage: is_connected('www.google.com')
 */
function is_connected($addr)
  {
    if (!$socket = @fsockopen($addr, 80, $num, $error, 5)) {
      echo "OFF";
    } else {
      echo "ON";
    }
  }
Shoifet answered 31/5, 2018 at 11:14 Comment(0)
C
1

Also note that fopen and fsockopen are different. fsockopen opens a socket depending on the protocol prefix. fopen opens a file or something else e.g file over HTTP, or a stream filter or something etc. Ultimately this affects the execution time.

Celibacy answered 18/9, 2020 at 11:18 Comment(0)
C
1

+1 on Alfred's answer, but I think this is an improved version:

function hasInternet()
{
    $hosts = ['1.1.1.1', '1.0.0.1', '8.8.8.8', '8.8.4.4'];

    foreach ($hosts as $host) {
        if ($connected = @fsockopen($host, 443)) {
            fclose($connected);
            return true;
        }
    }

    return false;
}

My reasons:

  • This pings more than 1 server and will only fail if all 4 fails
  • If first host works, it will return true immediately
  • IP addresses are from CloudFlare and Google DNS which basically controls most of the internet and always online
  • 1.1.1.1 is rated the fastest DNS resolver (Source)

Only doubt I have is to use port 443 or 80? Suggestions would be appreciated! :)

Cowell answered 1/9, 2021 at 15:12 Comment(0)
P
0

You could ping to a popular site or to the site you're wgetting from (like www.google.nl) then parse the result to see if you can connect to it.

<?php
$ip = '127.0.0.1'; //some ip
exec("ping -n 4 $ip 2>&1", $output, $retval);
if ($retval != 0) { 
echo "no!"; 
} 
else 
{ 
echo "yes!"; }
?>
Pyralid answered 1/2, 2011 at 8:35 Comment(3)
Except don't actually do it by IP address.Relief
And why not use some IP? That's exactly what happens behind the scenes using some a domain anyway.Giesecke
@Giesecke using a FQDN is smarter coding, that way you can update the DNS without having to update your codeWeakling
G
0

Just check the result of wget. A status code of 4 indicates a network problem, a status code of 8 indicates a server error (such as a 404). This only works if you call wget for each file in sequence, rather than once for all the files.

You can also use libcurl with PHP, instead of calling wget. Something like:

foreach (...) {
    $c = curl_init($url);
    $f = fopen($filepath, "w")
    curl_setopt($c, CURLOPT_FILE, $f);
    curl_setopt($c, CURLOPT_HEADER, 0);
    if (curl_exec($c)) {
        if (curl_getinfo($c, CURLINFO_HTTP_CODE) == 200) {
            // success
        } else {
            // 404 or something, delete file
            unlink($filepath);
        }
    } else {
        // network error or server down
        break; // abort
    }
    curl_close($c);
}
Godwin answered 1/2, 2011 at 9:13 Comment(0)
N
0

This function handles what you need

function isConnected()
{
    // use 80 for http or 443 for https protocol
    $connected = @fsockopen("www.example.com", 80);
    if ($connected){
        fclose($connected);
        return true; 
    }
    return false;
}
Notochord answered 14/1, 2017 at 9:10 Comment(0)
C
0

You can use this by adding this inside a class:

private $api_domain  = 'google.com';

private function serverAliveOrNot()
{
    if($pf = @fsockopen($this->api_domain, 443)) {
        fclose($pf);
        $_SESSION['serverAliveOrNot'] = true;
        return true;
    } else {
        $_SESSION['serverAliveOrNot'] = false;
        return false;
    }
}
Coastal answered 2/6, 2021 at 16:12 Comment(0)
C
0

Very PHP way of doing it is

<?php
switch (connection_status())
{
case CONNECTION_NORMAL:
  $txt = 'Connection is in a normal state';
  break;
case CONNECTION_ABORTED:
  $txt = 'Connection aborted';
  break;
case CONNECTION_TIMEOUT:
  $txt = 'Connection timed out';
  break;
case (CONNECTION_ABORTED & CONNECTION_TIMEOUT):
  $txt = 'Connection aborted and timed out';
  break;
default:
  $txt = 'Unknown';
  break;
}

echo $txt;
?>

https://www.w3schools.com/php/func_misc_connection_status.asp

Cephalic answered 8/8, 2022 at 10:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.