Here's what I use for doing ssh2_exec for long running scripts, expanding on other examples. It waits for a timeout and checks if both streams are finished. Does not use blocking and it gets data from both STDOUT and STDERR.
<?php
$stdout = ssh2_exec($ssh, $cmd);
$stderr = ssh2_fetch_stream($stdout, SSH2_STREAM_STDERR);
if (!empty($stdout)) {
$t0 = time();
$err_buf = null;
$out_buf = null;
do {
$err_buf.= fread($stderr, 4096);
$out_buf.= fread($stdout, 4096);
$done = 0;
if (feof($stderr)) {
$done++;
}
if (feof($stdout)) {
$done++;
}
$t1 = time();
$span = $t1 - $t0;
echo "while (($tD < 20) && ($done < 2));\n";
sleep(1);
} while (($span < 30) && ($done < 2));
echo "STDERR:\n$err_buf\n";
echo "STDOUT:\n$out_buf\n";
echo "Done\n";
} else {
echo "Failed to Shell\n";
}
?>
Adjust your timeout as necessary.