<?php
// The command to run.
$command = 'ping 127.0.0.1';
$descriptors = [
0 => ['pipe', 'r'], // STDIN
1 => ['pipe', 'w'], // STDOUT
2 => ['pipe', 'w'], // STDERR
];
$process = proc_open($command, $descriptors, $pipes);
if (is_resource($process)) {
fclose($pipes[0]);
$read_output = $read_error = false;
$buffer_len = $prev_buffer_len = 0;
$ms = 10;
$output = '';
$read_output = true;
$error = '';
$read_error = true;
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
// Dual reading of STDOUT and STDERR stops one full pipe blocking
// the other because the external script is waiting
while ($read_error != false or $read_output != false) {
if ($read_output != false) {
if (feof($pipes[1])) {
fclose($pipes[1]);
$read_output = false;
} else {
// STDOUT line.
// Check conditions here.
$str = trim(fgets($pipes[1]));
$len = strlen($str);
if ($len) {
$buffer_len += $len;
}
}
}
if ($read_error != false) {
if (feof($pipes[2])) {
fclose($pipes[2]);
$read_error = false;
} else {
// STDERR line.
// Check conditions here.
$str = trim(fgets($pipes[2]));
$len = strlen($str);
if ($len) {
$buffer_len += $len;
}
}
}
if ($buffer_len > $prev_buffer_len) {
$prev_buffer_len = $buffer_len;
$ms = 10;
} else {
usleep($ms * 1000); // sleep for $ms milliseconds
if ($ms < 160) {
$ms = $ms * 2;
}
}
}
proc_close($process);
}