2011-05-29 79 views
5

我试图做一个应用程序,它会检查它可以ping外面,但它永远不会停止。我怎样才能将命令应用到终端并停止操作?实施例在以下情况下:如何使用system()或passthru()应用终端命令时停止PHP?

$ php -r "echo system('ping 127.0.0.1');" 
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data. 
64 bytes from 127.0.0.1: icmp_req=1 ttl=64 time=0.073 ms 
64 bytes from 127.0.0.1: icmp_req=2 ttl=64 time=0.073 ms 
64 bytes from 127.0.0.1: icmp_req=3 ttl=64 time=0.072 ms 
64 bytes from 127.0.0.1: icmp_req=4 ttl=64 time=0.074 ms 
64 bytes from 127.0.0.1: icmp_req=5 ttl=64 time=0.071 ms 
64 bytes from 127.0.0.1: icmp_req=6 ttl=64 time=0.073 ms 
64 bytes from 127.0.0.1: icmp_req=7 ttl=64 time=0.074 ms 
64 bytes from 127.0.0.1: icmp_req=8 ttl=64 time=0.073 ms 
64 bytes from 127.0.0.1: icmp_req=9 ttl=64 time=0.074 ms 
64 bytes from 127.0.0.1: icmp_req=10 ttl=64 time=0.081 ms 
64 bytes from 127.0.0.1: icmp_req=11 ttl=64 time=0.072 ms 
64 bytes from 127.0.0.1: icmp_req=12 ttl=64 time=0.075 ms 

注:CTRL + C施加到停止但是这将通过Web浏览器来执行。

回答

1

这可以用proc_open完成。举例来说,这一计划只会让ping6跑了大约5秒钟:

<?php 
$descriptorspec = array(
    1 => array("pipe", "w"), 
); 

$process = proc_open('ping6 ::1', $descriptorspec, $pipes); 

$emptyarr = array(); 
$start = microtime(true); 
if (is_resource($process)) { 
    stream_set_blocking($pipes[1], 0); 
    while (microtime(true) - $start < 5) { 
     $pipesdup = $pipes; 
     if (stream_select($pipesdup, $emptyarr, $emptyarr, 0, 100000)) 
      echo fread($pipes[1], 100); 
    } 

    fclose($pipes[1]); 
    proc_terminate($process); 
} 

在你的情况,你可能要检查connection_aborted()。但是请注意,您必须继续发送(和清除)用户中止的数据才能被检测到。

+1

谢谢,我在Zend框架中看到他们也这样做:http://framework.zend.com/manual/en/zendx.console.process.unix.overview.html – YumYumYum 2011-05-29 18:25:09

+0

什么是详细的向后方法,当你可以调用具有正确标志的子进程。 – 2011-05-29 18:56:14

+0

@Tomalak 1)这个描述了一个通用的方法,它可以用于任何子进程而不仅仅是ping; 2)您可能需要在无限期的时间内运行ping,直到用户取消。 – Artefacto 2011-05-29 21:16:32

4

你不能。改为将-c参数传递给ping

+1

谢谢,$ ping -c 2 127.0.0.1工作。但是如果无尽的时间继续运行,这很奇怪。我们能不能得到任何命令我们触发它的processID返回或什么?并在睡眠后执行(4);杀(的ProcessID); ? – YumYumYum 2011-05-29 17:37:44

+0

不是'system()'和'passthru()'都不能让PHP脚本运行,所以不会有杀死进程的机会。 – 2011-05-29 17:38:34

+1

不完全正确。它不能用'system()'或'passthru()'完成,但是'proc_open()'完全可以。 – Artefacto 2011-05-29 17:53:50

1

system()是同步的,所以你不能。确保子进程终止。

在这个例子中,ping-c 4 127.0.0.1只发送四个ping数据包。

1

正确的操作过程不是停止进程,而是提供命令行参数以使其自行终止。您正在寻找的参数是-c count只发送固定数量的请求。有关更多信息,请参阅man ping