PHP在线ping域名IP测试通信的几个方法
有时候我们需要使用PHP代码模拟类似DOS的PING命令测试一个域名或者IP的通断情况或者测试域名对应的IP地址及延迟时间,TTL值等数据,这个时候就可以用以下代码来实现
有两种方式,第一种对系统函数要求不大,只要用fsockopen函数就行,第二个要求有exec函数来调用系统的ping,这个被很多虚拟主机给禁用了,因此必须有自己服务器权限,推荐用第一种
<?php $host = 'www.zzrrr.com'; $port = '80'; $num = 3; //Ping次数 //获取时间 function mt_f (){ list($usec,$sec) = explode(" ",microtime()); return ((float)$usec + (float)$sec); //微秒加秒 } function ping_f($host,$port){ $time_s = mt_f(); $ip = gethostbyname($host); $fp = @fsockopen($host,$port); if(!$fp) return 'reply time out!'; $get = "GET / HTTP/1.1\r\nHost:".$host."\r\nConnect:".$port."Close\r\n"; fputs($fp,$get); fclose($fp); $time_e = mt_f(); $time = $time_e - $time_s; $time = ceil($time * 1000); return 'reply from '.$ip.':'.$port.' time = '.$time.'ms<br />'; } echo 'ping to '.$host.' ['.gethostbyname($host).'] with port:'.$port.' of data:<br />'; for($i = 0;$i < $num;$i++){ echo ping_f($host,$port); //每次运行中间间隔1S sleep(1); //刷新输出缓存 ob_flush(); flush(); } ?>
第二种:用到的是php的内置函数exec来调用系统的ping命令,从而实现ping命令功能的。
<?php $to_ping='www.zzrrr.com'; $count=2; $psize=66; echo "正在执行php ping命令,请等待...\n<br><br>"; flush(); while(1){ echo "<pre>"; exec("ping -c $count -s $psize $to_ping", $list); for($i=0;$i<count($list);$i++){ print $list[$i]."\n"; } echo "</pre>"; flush(); sleep(3); } ?>
注意使用exec函数必须需要服务器支持调用系统内置函数才行。另外也可以使用system等php内置函数来实现这个功能。另外需要注意因为在windows和Linux里面PING命令的使用是略有不同的因此最好做个判断
类似这样
<?php echo 'PHP_INT_MAX : ' . PHP_INT_MAX . "<br><br>"; $ip = '115.29.237.28'; // IP地址 if (PATH_SEPARATOR==':') // linux { echo 'I am linux' . "<br><br>"; exec("ping -c 3 -w 5 $ip", $info); echo 'linux info : ' . "<br>"; print_r($info); $ping_time_line = end($info); echo '<br><br>ping_time_line : ' . $ping_time_line . "<br><br>"; $ping_time = explode("=", $ping_time_line)[1]; $ping_time_min = explode("/", $ping_time)[0] / 1000.0; $ping_time_avg = explode("/", $ping_time)[1] / 1000.0; $ping_time_max = explode("/", $ping_time)[2] / 1000.0; echo $ping_time_min . " " . $ping_time_avg . " " . $ping_time_max . "<br><br>"; } else // windows { echo 'I am windows' . "<br><br>"; exec("ping -c 3 -w 5 $ip", $info); echo 'windows info : ' . "<br>"; print_r($info); $info_time = end($info); echo '<br><br>info_time : ' . $info_time . "<br><br>"; } ?>
运行结果:
PHP_INT_MAX : 9223372036854775807
I am linux
linux info :
Array ( [0] => PING 115.29.237.28 (115.29.237.28) 56(84) bytes of data. [1] => 64 bytes from 115.29.237.28: icmp_seq=1 ttl=52 time=26.1 ms [2] => 64 bytes from 115.29.237.28: icmp_seq=2 ttl=52 time=27.5 ms [3] => 64 bytes from 115.29.237.28: icmp_seq=3 ttl=52 time=25.2 ms [4] => [5] => — 115.29.237.28 ping statistics — [6] => 3 packets transmitted, 3 received, 0% packet loss, time 2002ms [7] => rtt min/avg/max/mdev = 25.280/26.339/27.590/0.970 ms )
ping_time_line : rtt min/avg/max/mdev = 25.280/26.339/27.590/0.970 ms
0.02528 0.026339 0.02759
如果只需要取延时时间,那就封装成函数
function ping_time($ip) { $ping_cmd = "ping -c 3 -w 5 " . $ip; exec($ping_cmd, $info); $ping_time_line = end($info); $ping_time = explode("=", $ping_time_line)[1]; $ping_time_min = explode("/", $ping_time)[0] / 1000.0; $ping_time_avg = explode("/", $ping_time)[1] / 1000.0; $ping_time_max = explode("/", $ping_time)[2] / 1000.0; $result = array(); $result['ping_min'] = $ping_time_min; $result['ping_avg'] = $ping_time_avg; $result['ping_max'] = $ping_time_max; print_r($result); }
ping_time('115.29.237.28');
运行结果Array ( [ping_min] => 0.025497 [ping_avg] => 0.025947 [ping_max] => 0.026753 )
附录:
php手册对这exec和system二个函数的解释:
exec --- 执行外部程式
语法 : string exec ( string command [, array &output [, int &return_var]] )
说明 :
exec( )执行给予的命令command,不过它并不会输出任何东西,它简单的从命令的结果中传回最后一行,如果你需要去执行一个命令,并且从命令去取得所有资料时,可以使用passthru( )这个函数。
如果有给予参数array,则指定的数组将会被命令所输出的每一行填满,注意 : 如果数组先前已经包含了一些元素的话,exec( )将会把它附加在数组的后面,如果你不想要此函数附加元素的话,你可以在传递此数组给exec( )之前呼叫unset( )。
如果有给予参数array和return_var,则传回执行的状态命令将会写到这个变量。
意 : 如果你允许来自使用者输入的资料,可以传递到此函数,那么你应该使用escapeshellcmd( )来确定此使用者无法哄骗(trick)系统来执行武断的(arbitrary)命令。
注意 : 如果你使用此函数来启动一个程式,而且希望在背景里(background)执行的时候离开它,你必须确定此程式的输出是转向(redirected)到一个文件或是一些输出的资料流,否则PHP将会悬挂(hang)直到程式执行结束。
system --- 执行外部程式并且显示输出
语法 : string system ( string command [, int &return_var] )
说明 :
system( )执行给予的命令command,并且输出结果。如果有给予参数return_var,则执行命令的状态码将会写到这个变量。
注意 : 如果你允许来自使用者输入的资料,可以传递到此函数,那么你应该使用escapeshellcmd( )来确定此使用者无法哄骗(trick)系统来执行武断的(arbitrary)命令。
注意 : 如果你使用此函数来启动一个程式,而且希望在背景里(background)执行的时候离开它,你必须确定此程式的输出是转向(redirected)到一个文件或是一些输出的资料流,否则PHP将会悬挂(hang)直到程式执行结束。
这二个都是用来调用系统shell命令,不同点:
exec可以把执行的结果全部返回到$output函数里(数组),$status是执行的状态 0为成功 1为失败
systerm不需要提供$output函数,他是直接把结果返回出来,同样$return_var是执行的状态码 0为成功 1为失败
exec示例:
<?php $a = exec("dir",$out,$status); print_r($a); print_r($out); print_r($status); ?>
system示例:
<?php $a = system("dir",$out); print_r($a); print_r($out); ?>
- 最新评论