Skip to content

Instantly share code, notes, and snippets.

@turboezh
Created April 21, 2016 15:38
Show Gist options
  • Save turboezh/97107a01ec926eb5f84ef6e49e2a0586 to your computer and use it in GitHub Desktop.
Save turboezh/97107a01ec926eb5f84ef6e49e2a0586 to your computer and use it in GitHub Desktop.
Communicate to process by pipes
<?php
namespace app\helpers;
use Yii;
use yii\base\Exception;
/**
*
*/
class ProcessHelper
{
/**
* @param string $cmd
* @param string $stdInData
*
* @return string|null
* @throws Exception
*/
public static function pipe($cmd, $stdInData = null)
{
$stdOutData = null;
$descriptorSpec = [
0 => ["pipe", "r"], // stdin - канал, из которого дочерний процесс будет читать
1 => ["pipe", "w"], // stdout - канал, в который дочерний процесс будет записывать
2 => ["pipe", "w"], // stderr - файл для записи
];
$cwd = Yii::getAlias('@runtime');
$process = proc_open($cmd, $descriptorSpec, $pipes, $cwd);
if (is_resource($process)) {
// $pipes теперь выглядит так:
// 0 => записывающий обработчик, подключенный к дочернему stdin
// 1 => читающий обработчик, подключенный к дочернему stdout
// Вывод сообщений об ошибках будет добавляться в /tmp/error-output.txt
if (strlen($stdInData)) {
fwrite($pipes[0], $stdInData);
}
fclose($pipes[0]);
$stdOutData = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stdErrorData = stream_get_contents($pipes[2]);
fclose($pipes[2]);
// Важно закрывать все каналы перед вызовом
// proc_close во избежание мертвой блокировки
$returnValue = proc_close($process);
if ($returnValue) {
throw new Exception($stdErrorData);
}
}
return $stdOutData;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment