I want to use Ghostscript command within PHP without writing the input or output in files.
$cmd = "gs -sOutputFile=%stdout% -sDEVICE=pdfwrite -dJOBSERVER -";
$descriptorspec = array(0 => array("pipe", "r"),1 => array("pipe", "w"));
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
fwrite($pipes[0], file_get_contents('file.ps'));
fclose($pipes[0]);
$pdf_content = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$return_value = proc_close($process);
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="output.pdf"');
echo $pdf_content;
}
Writting to STDOUT works well, but I cannot get the STDIN to work. If replacing the command line to
$cmd = "gs -sOutputFile=%stdout% -sDEVICE=pdfwrite -dNOSAFER file.ps";
it works well, but it doesn't when trying to read the input from $pipes[0]. Where did I go wrong?
1 Answer 1
You need to supply '-' as the input filename. So for example:
gs -sDEVICE=pdfwrite -o out.pdf - < /ghostpdl/examples/golfer.eps
Tells Ghostscript to take input from stdin, and directs the content of that file into stdin.
However, for PDF input if you send the input on stdin it is written to a temporary file on disk and then processed, because PDF requires random access to the file, it isn't a streamable format.
For PDF output I would very much advise against writing to stdout. There is already one feature which requires the code to seek inside the output file, and in future there may be more. Obviously that won't be possible if you write the output to stdout so I'd really recommend you don't do that.
3 Comments
gs -sDEVICE=pdfwrite -o out.pdf - < in.ps and gs -sDEVICE=pdfwrite -o out.pdf -dNOSAFER in.ps. And how does cat in.ps | gs -sDEVICE=pdfwrite -o out.pdf work? I didn't catch the drawback of echoing the output instead of writing it to a file.
file_get_contentsinstead of the direct variable). The output is a corrupt PDF. I am not sure how I can report the error since the output contains binary data. What can be the alternative to GS here?tee. Compare what you put in and what came out. Question is whether GS is the cause of the problem or the way you redirect stdin/stdout. BTW: 2 should be stderr, but you don't supply a pipe for that. Is that intended? Don't you miss (possibly important) error info from that?php://stdin. I think the stdin read by GS is not what was expected (possible an opening or ending character). I dropped the third pipeline of stderr for the sake of simplicity. I was unable to catch any error there.