【问题标题】:Determine in php script if connected to internet?如果连接到互联网,请在 php 脚本中确定?
【发布时间】:2011-02-01 08:29:41
【问题描述】:

如何通过在我的开发机器上运行的 PHP 脚本检查我是否已连接到互联网?

我运行脚本以使用 wget 下载一组文件(可能存在也可能不存在)。如果我在没有连接的情况下尝试下载,wget 会继续下一个,认为文件不存在。

【问题讨论】:

    标签: php internet-connection


    【解决方案1】:
    <?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;
    
    }
    ?>
    

    【讨论】:

    • + 不错的答案是其他人可能认为[80|443] 会在任何端口之间切换... :)
    • 基于this 帖子,使用example.com 作为答案的“www.some_domain.com”可能很有意义。
    【解决方案2】:

    您总是可以 ping 好“ol 值得信赖的 google”:

    $response = null;
    system("ping -c 1 google.com", $response);
    if($response == 0)
    {
        // this means you are connected
    }
    

    【讨论】:

    • 这是相当可靠的,但请记住,“ICMP 有效!= TCP 有效”(防火墙、NAT 等),甚至“TCP 有效!= HTTP 有效”(透明代理等) .).
    【解决方案3】:

    此代码在 laravel 4.2 php 框架中失败,并出现内部服务器 500 错误:

    <?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;
        }
    ?>
    

    我不想强迫自己弄清楚这一点,因此我尝试了这段代码,它对我有用:

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

    请注意:这是基于与 google.com 的连接不太容易失败的假设。

    【讨论】:

    • 不错的选择!这也需要 php.ini 中的 allow_url_fopen = On
    • 在我的测试中 fopen 比 fsockopen 慢两倍。此外,这种语法会比带有 return true/false 的丑陋 if() 看起来更好: return (bool) fopen("google.com:80/","r");
    【解决方案4】:

    接受的答案对我不起作用。当互联网断开连接时,它引发了一个php错误。所以我使用它进行了一些修改,如下所示:

    if(!$sock = @fsockopen('www.google.com', 80))
    {
        echo 'Not Connected';
    }
    else
    {
    echo 'Connected';
    }
    

    【讨论】:

      【解决方案5】:

      为什么不从 wget 获取返回码来判断下载是否成功呢?可以在wget exit status 找到可能值的列表。

      另一方面,您也可以使用 php 的 curl functions,然后您可以在 PHP 中进行所有错误跟踪。

      【讨论】:

        【解决方案6】:

        有多种因素决定互联网连接。例如,接口状态。但是,不管怎样,由于网络的性质,正确的配置并不意味着你有一个有效的连接。

        因此,最好的方法是尝试下载您确定存在的文件。如果你成功了,你可以按照接下来的步骤。如果没有,请重试一次,然后失败。

        尝试在目标主机上选择一个。如果不可能,请选择一些主要的网站,例如 google 或 yahoo。

        最后,只需尝试检查 wget 返回的错误代码。我敢打赌,对于 404-s 和超时,这些是不同的。您可以在exec 调用中使用第三个参数:

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

        【讨论】:

          【解决方案7】:
          /*
           * Usage: is_connected('www.google.com')
           */
          function is_connected($addr)
            {
              if (!$socket = @fsockopen($addr, 80, $num, $error, 5)) {
                echo "OFF";
              } else {
                echo "ON";
              }
            }
          

          【讨论】:

            【解决方案8】:

            还要注意fopenfsockopen 是不同的。 fsockopen 根据协议前缀打开一个套接字。 fopen 打开文件或其他东西,例如通过 HTTP 的文件,或流过滤器或其他东西等。最终这会影响执行时间。

            【讨论】:

              【解决方案9】:

              您可以 ping 到一个受欢迎的网站或您要访问的网站(例如 www.google.nl),然后解析结果以查看您是否可以连接到它。

              <?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!"; }
              ?>
              

              【讨论】:

              • 除非实际上不按 IP 地址进行。
              • 为什么不使用一些IP?无论如何,这正是使用某个域在幕后发生的事情。
              • @killstreet 使用 FQDN 是更智能的编码,这样您就可以更新 DNS 而无需更新您的代码
              【解决方案10】:

              只需检查wget 的结果。状态码 4 表示网络问题,状态码 8 表示服务器错误(例如 404)。这仅适用于您按顺序为每个文件调用 wget,而不是为所有文件调用一次。

              您也可以在 PHP 中使用libcurl,而不是调用 wget。比如:

              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);
              }
              

              【讨论】:

                【解决方案11】:

                这个函数处理你需要的东西

                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;
                }
                

                【讨论】:

                  【解决方案12】:

                  您可以通过在类中添加它来使用它:

                  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;
                      }
                  }
                  

                  【讨论】:

                    【解决方案13】:

                    +1 对 Alfred 的回答,但我认为这是一个改进版本:

                    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;
                    }
                    

                    我的理由:

                    • 这会 ping 超过 1 个服务器,并且仅当所有 4 个服务器都失败时才会失败
                    • 如果第一个主机工作,它将立即返回true
                    • IP 地址来自 CloudFlare 和 Google DNS,它们基本上控制着大部分互联网并始终在线
                    • 1.1.1.1 被评为最快的 DNS 解析器 (Source)

                    我唯一的疑问是使用端口 443 还是 80?建议将不胜感激! :)

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2015-07-08
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多