如何在使用system()或passthru()应用终端命令时停止PHP


How to stop PHP while applying a terminal command using system() or passthru()?

我正在尝试制作一个应用程序,该应用程序将检查它是否可以在外部ping,但它永远不会停止。如何将命令应用于终端并停止操作?以下情况下的示例:

$ 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浏览器执行。

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

正确的做法不是停止进程,而是向ping提供命令行参数,使其自行终止。您要查找的参数是-c count,它只发送固定数量的请求。有关详细信息,请参见man ping

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

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

这可以通过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()。但请注意,您必须不断发送(和刷新)数据,以便检测到用户中止。