proc_open() php 関数を使用するときに、プロセスにパイプされるストリームの使用に問題があるようです。
私が始めようとしているプロセスは、3 つの画像を重ね合わせて作成するための単純な変換 ImageMagick ユーティリティです。1 つの入力ストリーム (STDIN) のみが使用され、変数がそのストリームにダンプされる場合、変換プログラムは正常に動作し、次のように変数に格納できる出力を返します。
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= ' -size SOMESIZE ';
$cmd .= ' -background black ';
$cmd .= ' -fill white ';
$cmd .= ' -stroke none ';
$cmd .= ' -gravity center ';
$cmd .= ' -trim ';
$cmd .= ' -interline-spacing SOMELINEHEIGHT ';
$cmd .= ' -font SOMEFONT ';
$cmd .= ' label:"SOMETEXT" ';
$cmd .= ' miff:- ';
$ctext_opacity = shell_exec($cmd);
最初に変換を実行し、出力を $ctext_opacity 変数に保存します。次に、proc_open() を介して次のコマンドが呼び出され、$ctext_opacity 変数が STDIN を介してパイプされ、入力イメージとして使用されます。
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= '-size SOMESIZE ';
$cmd .= ' xc:\'rgb(230, 225, 50)\' ';
$cmd .= ' -gravity center ';
$cmd .= ' - '; // ImageMagick uses dash(-) for STDIN
$cmd .= ' -alpha Off ';
$cmd .= ' -compose CopyOpacity ';
$cmd .= ' -composite ';
$cmd .= ' -trim ';
$cmd .= ' miff:- ';
$chighlight = '';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], $ctext_opacity);
fclose($pipes[0]);
while (!feof($pipes[1])) {
$chighlight .= fgets($pipes[1]); // HERE WE FEED THE OUTPUT OF "CONVERT" TO $chighlight
}
//echo $chighlight; die();
fclose($pipes[1]);
$return_value = proc_close($process);
}
上記のコマンドは 3 回呼び出され、3 つの個別の画像が生成され、3 つの変数に格納されます。次のコマンドは、これら 3 つの変数を入力イメージとして受け入れることになっています (ImageMagic 構文は、fd:N のような代替 io ストリームを指定します。ここで、N は、proc_open() によって生成されたストリームの番号です)。ただし、入力ストリームへの書き込みまたは STDOUT からの読み取りが間違っているようです。おそらく、プロセスからの出力がフラッシュされず、終了せずにハングする可能性があります。
$cmd = BIN_PATH.DIRECTORY_SEPARATOR.'convert ';
$cmd .= ' -size SOMESIZE ';
$cmd .= ' xc:transparent ';
$cmd .= ' -gravity center ';
$cmd .= ' - -geometry -2-2 -composite ';
$cmd .= ' fd:3 -geometry +2+2 -composite ';
$cmd .= ' fd:4 -composite ';
$cmd .= 'png:- ';
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w"),
2 => array("pipe", "a"),
3 => array("pipe", "r"),
4 => array("pipe", "r")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
$read = null;
$rd = array($pipes[1]);
$write = array($pipes[0], $pipes[3], $pipes[4]);
$wt = array($pipes[0], $pipes[3], $pipes[4]);
$im_args = array($cshade, $chighlight, $ctext);
$except = null;
$readTimeout = 1;
$ctext_deboss = '';
$numchanged = stream_select($read, $write, $except, $readTimeout);
foreach($write as $w) {
$key = array_search($w, $wt);
fwrite($wt[$key], $im_args[$key]);
fclose($wt[$key]);
$read = array($pipes[1]);
$rd = array($pipes[1]);
$write = null;
$except = null;
$readTimeout = 1;
$ctext_deboss = '';
$numchanged = stream_select($read, $write, $except, $readTimeout);
foreach($read as $r) {
while (!feof($r)) {
$ctext_deboss .= fgets($pipes[1]);
}
}
fclose($pipes[1]);
$return_value = proc_close($process);
echo $ctext_deboss; die();
}
}
変換が空/不正なデータでエラーをスローするため、3 & 4 パイプの内容を転送できないようです