Attention! All reasoning refers to running PHP in CLI mode, and not as a web server module!
If you have ever used the system () function in PHP, you probably wondered how system () returns the last line for a command, and also displays the results of a command to a web page, and not to yourself somewhere on the stdout web -server? And why does system () work differently than system () in C? The answer, in general, is simpler than it might seem.
In fact, system () in PHP uses the same function as exec () (
int php_exec (int type, char * cmd, pval * array, pval * return_value TSRMLS_DC) ), it just outputs the result line by line, not accumulating it into an array like exec (), and using only a string as a buffer. By the way, this behavior is hinted at by the documentation for the system () function:
For each system (if php), it is running as a server module.
And php_exec basically uses popen () to execute the corresponding command, which means there is a possibility that the program being called may “not recognize” STDIN as a terminal and issue a response in a different format than when launched through the shell.
Solving the progressive buffing problem system ()
If you just want to make sure that you have information displayed as it is received, without accumulating line by line, you can simply use passthru instead of system. This is enough for, say, git clone to display the progress of the operation correctly, but at the same time, ls will still display information in one column, because, in fact, passthru also uses php_exec, which means popen, with all resulting consequences
')
Solution with proc_open ()
If you want, say, ls to display the same information as it does when launched from the terminal, and if you need support for colors, you can use proc_open:
$handle = proc_open("ls", array(0=>STDIN,1=>STDOUT,2=>STDERR), $pipes); $retval = proc_close($handle);
UNIX way
In principle, the above methods should be enough for you to work.
But if you need any special perversions, or you want to completely control what happens when you start the program, you can try to solve this problem with the old UNIX way: via fork-exec (this will work only under * nix and availability of pcntl extension):
function libcSystem($cmd) { $pid = pcntl_fork(); if($pid < 0) { return -1; } if($pid == 0) { pcntl_exec('/bin/sh', array('-c', $cmd), $_ENV); exit(127); } pcntl_waitpid($pid, $status); return pcntl_wexitstatus($status); }
I hope this article will be useful to those who write PHP scripts for the CLI and want to understand how to make system () work as it should in theory work.