user285594
user285594

Reputation:

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

I am trying to make a application which will check it can ping outside but it never stop. How can i apply a command to terminal and stop the action? Example in following case:

$ 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

Note: ctrl+c was applied to stop but this will be executed via web browser.

Upvotes: 5

Views: 925

Answers (4)

Artefacto
Artefacto

Reputation: 97835

This can be done with proc_open. For instance, this program will only let ping6 run for around 5 seconds:

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

In your case, you might want to check connection_aborted(). But notice you have to keep sending (and flushing) data for the user abort to be detected.

Upvotes: -1

pfhayes
pfhayes

Reputation: 3927

The correct course of action is not to halt the process, but supply command-line arguments to ping so that it terminates on its own. The argument you are looking for is -c count to only send a fixed number of requests. See man ping for more information.

Upvotes: 1

Lightness Races in Orbit
Lightness Races in Orbit

Reputation: 385174

system() is synchronous, so you can't. Ensure that the child process terminates.

In this example, ping-c 4 127.0.0.1 to only send four ping packets.

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798686

You can't. Pass the -c argument to ping instead.

Upvotes: 3

Related Questions