I’m writing a wrapper for mysqldump
and want to show the output nicely in a PHP CLI application.
I’m attempting to run mysqldump -v
using popen
so that I can get the verbose output and display progress indicators to the user. However no output is returned (by default it gets logged to the screen via stdErr
).
I tried adding 2>&1
to the command to push the verbose output from stdErr
to stdOut
, but fread
still doesn’t get any output even though the output nolonger goes to the screen via stdErr
.
$cmd = "mysqldump -uroot -proot -v dbname 2>&1 | mysql -uroot -proot dbname2";
$handle = popen($cmd, "r");
$buffer = "";
while ($handle && !feof($handle)){
$output = fread($handle, 100);
$buffer .= $output;
echo sprintf("Buffer: %sn", $buffer);
}
pclose($handle);
Should I use something else instead of popen
? Or am I simply incorrectly redirecting the output?
Advertisement
Answer
I figured it out, without having to use a file as a stream buffer.
/**
* PROCESS
*
* Process the command
*
* @param int $buffer The size of the buffer
* @param int $pipe The pipe to subscribe to (0=stdIn, 1=stdOut, 2=stdErr)
*
* @return bool Success or not
*/
public function process($buffer=10, $pipe=1) {
$handle = proc_open(
$this->command,
[
["pipe","r"],
["pipe","w"],
["pipe","w"]
],
$pipes
);
if (!is_resource($handle)) {
return false;
}
$output = "";
$buffer = "";
$hasLineCallbacks = count($this->onNewLine);
while ($buffer = fread($pipes[$pipe], 10)) {
$output .= $buffer;
if (preg_match("/[rn]/", $output)) {
$segments = preg_split("/[rn]+/", $output);
while (count($segments) > 1) {
$line = array_shift($segments);
if (!$hasLineCallbacks) { continue; }
foreach ($this->onNewLine as $callback) {
if (!$callback["pattern"] || preg_match($callback["pattern"], $line)) {
call_user_func($callback["callback"], $line);
}
}
}
$output = array_shift($segments);
}
}
proc_close($handle);
return true;
}
I’m basically making Background
class to run a terminal command and pipe the output to callback functions. It obviously still has a long way to go though.
Thanks for your help, @Victor