Я пытаюсь написать PHP script, который использует приложение pdftk для слияния XFDF с формой PDF и вывода слияние PDF с пользователем. Согласно документации pdftk, я могу передавать данные формы через stdin
и иметь выход PDF в поток stdout
. Обычный, не файловый способ использования pdftk из командной строки:
pdftk blankform.pdf fill_form formdata.xfdf output filledform.pdf
чтобы использовать потоки в командной строке, вы должны ввести:
pdftk blankform.pdf fill_form - output -
У меня есть пара проблем:
1) Я получил pdftk для возврата вывода через stdout
с помощью файла xfdf (вместо stdin
), например:
exec("pdftk blankform.pdf fill_form formdata.xfdf output -", $pdf_output);
file_put_contents("filledform.pdf",$pdf_output);
Но pdf файл, который он создает, поврежден, согласно Adobe Reader, и быстрый просмотр файла с текстовым редактором показывает, что, по крайней мере, он не устанавливает окончания строк, где они должны быть. У меня есть идентичный PDF файл, созданный pdftk, где он выводится в файл, а pdf отлично выглядит в текстовом редакторе, поэтому я знаю, что он не pdftk, который выводит плохие данные.
2) Я не могу на всю жизнь выяснить, как установить поток stdin
в PHP, чтобы я мог использовать этот поток в качестве моего ввода для pdftk. Из того, что я читаю в документации PHP, stdin
доступен только для чтения, так как что-то происходит в этом потоке?
В идеале я хотел бы сделать это очень простым и не использовать proc_open()
. Я попытался использовать эту функцию и не был очень успешным, это, вероятно, моя ошибка, а не функция, но на самом деле мои цели достаточно просты, я бы предпочел избежать использования надежных функций, которые мне не нужны.
В идеале мой код будет выглядеть примерно так:
$form_data_raw = $_POST;
$form_data_xfdf = raw2xfdf($form_data_raw); //some function that turns HTML-form data to XFDF
$blank_pdf_form = "blankform.pdf";
header('Content-type: application/pdf');
header('Content-Disposition: attachment; filename="output.pdf"');
passthru("pdftk $blank_pdf_form fill_form $form_data_xfdf output -);
Просто голова, можно поместить фактическую строку xml в командной строке, но у меня были очень ненадежные результаты с этим.
Изменить
С большой помощью я теперь понимаю, что мой реальный вопрос: "Как передать переменную в выполнение командной строки в PHP". По-видимому, proc_open - лучший способ пойти или, по крайней мере, самый простой. Поскольку мне потребовалось много времени, чтобы понять это, и поскольку мои исследования в Google говорят о том, что другие могут борется, я отправлю код, который специально работал для моей проблемы:
$blank_pdf_form = "blankform.pdf";
$cmd = "pdftk $blank_pdf_form fill_form - output -";
$descriptorspec = array(
0 => array("pipe", "r"),
1 => array("pipe", "w")
);
$process = proc_open($cmd, $descriptorspec, $pipes);
if (is_resource($process)) {
//row2xfdf is made-up function that turns HTML-form data to XFDF
fwrite($pipes[0], raw2xfdf($_POST));
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;
}