Попытка в PHP для mysqldump -v, чтобы открыть и не получить вывод

Я пишу обертку для mysqldump и хочу показать результат красиво в приложении CLI PHP.

Я пытаюсь бежать mysqldump -v с помощью popen так что я могу получить подробный вывод и отобразить индикаторы прогресса для пользователя. Однако вывод не возвращается (по умолчанию он регистрируется на экране через stdErr).

Я пытался добавить 2>&1 к команде, чтобы нажать подробный вывод из stdErr в stdOut, но fread до сих пор не получает никакого вывода, хотя выходной Nolonger идет на экран через 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: %s\n", $buffer);
}
pclose($handle);

Должен ли я использовать что-то другое вместо popen? Или я просто неправильно перенаправляю вывод?

0

Решение

Вы, кажется, на самом деле передаете данные mysqldump в mysql, и в этом случае может быть плохой идеей включать сообщения об ошибках в канал.

Конечно, в этом сценарии вы не можете захватить вывод mysqldump.

Вы должны использовать tee команда:

mysqldump -uroot -proot -v dbname | tee /tmp/output | mysql -uroot -proot dbname2

Таким образом, вы можете получить как в трубе для MySQL и /tmp/output,
Таким образом, вы можете тогда fopen /tmp/output для результатов.

Обратите внимание, что у вас могут не быть возможных ошибок в выходных данных, так как mysql не будет рад видеть их позже.

1

Другие решения

Я понял это, не используя файл в качестве буфера потока.

/**
* 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("/[\r\n]/", $output)) {
$segments = preg_split("/[\r\n]+/", $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;
}

Я в основном делаю Background класс для запуска команды терминала и передачи вывода в функции обратного вызова. Это, очевидно, еще предстоит пройти долгий путь.

Спасибо за вашу помощь, @Victor

0

По вопросам рекламы [email protected]