Как передать переменные как stdin в командную строку от PHP

Я пытаюсь записать Сценарий PHP, который использует pdftk приложение, чтобы объединить XFDF с формой PDF и произвести объединенный PDF пользователю. Согласно pdftk документации, я могу передать данные формы на пути stdin и произведите PDF к stdout поток. Нормальное, file-not-stream способ использовать 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;
}

28
задан Anthony 6 March 2010 в 03:50
поделиться

2 ответа

Я не уверен в том, чего вы пытаетесь достичь. Вы можете читать стандартный ввод с помощью URL-адреса php: // stdin. Но это стандартный ввод из командной строки PHP, а не из pdftk (через exec).

Но я дам +1 для proc_open ()


<?php

$cmd = sprintf('pdftk %s fill_form %s output -','blank_form.pdf', raw2xfdf($_POST));

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is a pipe that the child will read from
   1 => array("pipe", "w"),  // stdout is a pipe that the child will write to
   2 => null,
);

$process = proc_open($cmd, $descriptorspec, $pipes);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout

    fwrite($pipes[0], stream_get_contents(STDIN)); // file_get_contents('php://stdin')
    fclose($pipes[0]);

    $pdf_content = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);


    header('Content-type: application/pdf');
    header('Content-Disposition: attachment; filename="output.pdf"');
    echo $pdf_content;
}
?>
28
ответ дан 28 November 2019 в 03:48
поделиться

1) Почему вы выводите данные в стандартный вывод, а затем помещаете их в файл? Почему бы просто не сделать дамп pdftk в файл, т.е.

exec("pdftk blankform.pdf fill_form formdata.xfdf output filledform.pdf");

2) Используйте proc_open(). Не стесняйтесь публиковать любые проблемы, которые у вас возникли с этой функцией.

-1
ответ дан 28 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: