Program execution in php - display and return output

There are several methods in php to execute a shell command:

  • system()
  • PassThru ()
  • shell_exec ()
  • Exec ()

The first two conclusions are output, but do not return it. The last two outputs are output, but do not display it.

I want to run a shell command that takes a lot of time, but it displays some output, so I know that it does not hang. However, in the end I want to process this output in php. If I choose one of the first two, I will not get the output, so I can not process it in php. If I run one of the last two, I can process the output, however, my program will hang for a very long time without outputting anything.

Is there a way to run a shell command that will immediately display the output and return it?

+6
source share
2 answers

Maybe this one will interest you? proc_open() - http://www.php.net/manual/en/function.proc-open.php

And here is a handy snippet that might work for you (it is copied from the comments on the site on which I gave you the link):

 <?php /* * Execute and display the output in real time (stdout + stderr). * * Please note this snippet is prepended with an appropriate shebang for the * CLI. You can re-use only the function. * * Usage example: * chmod u+x proc_open.php * ./proc_open.php "ping -c 5 google.fr"; echo RetVal=$? */ define(BUF_SIZ, 1024); # max buffer size define(FD_WRITE, 0); # stdin define(FD_READ, 1); # stdout define(FD_ERR, 2); # stderr /* * Wrapper for proc_*() functions. * The first parameter $cmd is the command line to execute. * Return the exit code of the process. */ function proc_exec($cmd) { $descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w") ); $ptr = proc_open($cmd, $descriptorspec, $pipes, NULL, $_ENV); if (!is_resource($ptr)) return false; while (($buffer = fgets($pipes[FD_READ], BUF_SIZ)) != NULL || ($errbuf = fgets($pipes[FD_ERR], BUF_SIZ)) != NULL) { if (!isset($flag)) { $pstatus = proc_get_status($ptr); $first_exitcode = $pstatus["exitcode"]; $flag = true; } if (strlen($buffer)) echo $buffer; if (strlen($errbuf)) echo "ERR: " . $errbuf; } foreach ($pipes as $pipe) fclose($pipe); /* Get the expected *exit* code to return the value */ $pstatus = proc_get_status($ptr); if (!strlen($pstatus["exitcode"]) || $pstatus["running"]) { /* we can trust the retval of proc_close() */ if ($pstatus["running"]) proc_terminate($ptr); $ret = proc_close($ptr); } else { if ((($first_exitcode + 256) % 256) == 255 && (($pstatus["exitcode"] + 256) % 256) != 255) $ret = $pstatus["exitcode"]; elseif (!strlen($first_exitcode)) $ret = $pstatus["exitcode"]; elseif ((($first_exitcode + 256) % 256) != 255) $ret = $first_exitcode; else $ret = 0; /* we "deduce" an EXIT_SUCCESS ;) */ proc_close($ptr); } return ($ret + 256) % 256; } /* __init__ */ if (isset($argv) && count($argv) > 1 && !empty($argv[1])) { if (($ret = proc_exec($argv[1])) === false) die("Error: not enough FD or out of memory.\n"); elseif ($ret == 127) die("Command not found (returned by sh).\n"); else exit($ret); } ?> 
+2
source

Perhaps you can use popen () , which executes the program and reads its output through a file descriptor, for example:

 $handle = popen('/bin/ls', 'r'); while ($line = fread($handle, 100)){ echo $line; } pclose($handle); 
+2
source

Source: https://habr.com/ru/post/909459/


All Articles