php://memory
およびphp://temp
(実際にはすべてのファイル記述子) は、現在実行中の php プロセスでのみ使用できます。また、$tempFdfVirtual
リソース ハンドルなので、文字列に入れても意味がありません。
標準入力を介して、リソース ハンドルからプロセスにデータを渡す必要があります。でこれを行うことができます。これによりproc-open
、子プロセスへの入出力を よりも細かく制御できますexec
。
何らかの理由で、「php://memory」ファイル記述子をプロセスに渡すことができないことに注意してください。PHPは文句を言います:
警告: proc_open(): タイプ MEMORY のストリームをファイル記述子として表すことはできません
代わりに使用してくださいphp://temp
。これは、ストリームが十分に大きくなると一時ファイルを使用することを除いて、まったく同じであるはずです。
これは、 を使用するコードの一般的なパターンを示すテスト済みの例ですproc_open()
。これは、関数またはその他の抽象化でラップする必要があります。
$testinput = "THIS IS A TEST STRING\n";
$fp = fopen('php://temp', 'r+');
fwrite($fp, $testinput);
rewind($fp);
$cmd = 'cat';
$dspec = array(
0 => $fp,
1 => array('pipe', 'w'),
);
$pp = proc_open($cmd, $dspec, $pipes);
// busywait until process is finished running.
do {
usleep(10000);
$stat = proc_get_status($pp);
} while($stat and $stat['running']);
if ($stat['exitcode']===0) {
// index in $pipes will match index in $dspec
// note only descriptors created by proc_open will be in $pipes
// i.e. $dspec indexes with an array value.
$output = stream_get_contents($pipes[1]);
if ($output == $testinput) {
echo "TEST PASSED!!";
} else {
echo "TEST FAILED!! Output does not match input.";
}
} else {
echo "TEST FAILED!! Process has non-zero exit status.";
}
// cleanup
// close pipes first, THEN close process handle.
foreach ($pipes as $pipe) {
fclose($pipe);
}
// Only file descriptors created by proc_open() will be in $pipes.
// We still need to close file descriptors we created ourselves and
// passed to it.
// We can do this before or after proc_close().
fclose($fp);
proc_close($pp);
PDFTK の使用に固有の未テストの例:
// Command takes input from STDIN
$command = "pdftk unfilled.pdf fill_form - output tempfile.pdf flatten";
$descriptorspec = array(
0 => $tempFdfVirtual, // feed stdin of process from this file descriptor
// 1 => array('pipe', 'w'), // Note you can also grab stdout from a pipe, no need for temp file
);
$prochandle = proc_open($command, $descriptorspec, $pipes);
// busy-wait until it finishes running
do {
usleep(10000);
$stat = proc_get_status($prochandle);
} while ($stat and $stat['running']);
if ($stat['exitcode']===0) {
// ran successfully
// output is in that filename
// or in the file handle in $pipes if you told the command to write to stdout.
}
// cleanup
foreach ($pipes as $pipe) {
fclose($pipe);
}
proc_close($prochandle);