【发布时间】:2011-02-01 08:29:41
【问题描述】:
如何通过在我的开发机器上运行的 PHP 脚本检查我是否已连接到互联网?
我运行脚本以使用 wget 下载一组文件(可能存在也可能不存在)。如果我在没有连接的情况下尝试下载,wget 会继续下一个,认为文件不存在。
【问题讨论】:
如何通过在我的开发机器上运行的 PHP 脚本检查我是否已连接到互联网?
我运行脚本以使用 wget 下载一组文件(可能存在也可能不存在)。如果我在没有连接的情况下尝试下载,wget 会继续下一个,认为文件不存在。
【问题讨论】:
<?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] 会在任何端口之间切换... :)
您总是可以 ping 好“ol 值得信赖的 google”:
$response = null;
system("ping -c 1 google.com", $response);
if($response == 0)
{
// this means you are connected
}
【讨论】:
此代码在 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 的连接不太容易失败的假设。
【讨论】:
allow_url_fopen = On
接受的答案对我不起作用。当互联网断开连接时,它引发了一个php错误。所以我使用它进行了一些修改,如下所示:
if(!$sock = @fsockopen('www.google.com', 80))
{
echo 'Not Connected';
}
else
{
echo 'Connected';
}
【讨论】:
为什么不从 wget 获取返回码来判断下载是否成功呢?可以在wget exit status 找到可能值的列表。
另一方面,您也可以使用 php 的 curl functions,然后您可以在 PHP 中进行所有错误跟踪。
【讨论】:
有多种因素决定互联网连接。例如,接口状态。但是,不管怎样,由于网络的性质,正确的配置并不意味着你有一个有效的连接。
因此,最好的方法是尝试下载您确定存在的文件。如果你成功了,你可以按照接下来的步骤。如果没有,请重试一次,然后失败。
尝试在目标主机上选择一个。如果不可能,请选择一些主要的网站,例如 google 或 yahoo。
最后,只需尝试检查 wget 返回的错误代码。我敢打赌,对于 404-s 和超时,这些是不同的。您可以在exec 调用中使用第三个参数:
string exec(string $command [, array &$output [, int &$return_var ]])
【讨论】:
/*
* Usage: is_connected('www.google.com')
*/
function is_connected($addr)
{
if (!$socket = @fsockopen($addr, 80, $num, $error, 5)) {
echo "OFF";
} else {
echo "ON";
}
}
【讨论】:
还要注意fopen 和fsockopen 是不同的。 fsockopen 根据协议前缀打开一个套接字。 fopen 打开文件或其他东西,例如通过 HTTP 的文件,或流过滤器或其他东西等。最终这会影响执行时间。
【讨论】:
您可以 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!"; }
?>
【讨论】:
只需检查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);
}
【讨论】:
这个函数处理你需要的东西
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;
}
【讨论】:
您可以通过在类中添加它来使用它:
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;
}
}
【讨论】:
+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;
}
我的理由:
true
我唯一的疑问是使用端口 443 还是 80?建议将不胜感激! :)
【讨论】: