如何将变量作为stdin从PHP传递到命令行

我正在尝试编写一个使用pdftk应用程序的PHP脚本,以将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);

但是,根据Adobe

Reader的显示,它创建的pdf损坏,并且使用文本编辑器快速浏览该文件表明,至少,它没有将行尾设置在应有的位置。我有一个由pdftk创建的完全相同的PDF,它将输出到文件中,并且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;

}

回答:

我不确定您要达到的目标。您可以使用URL php://

stdin阅读stdin。但这是PHP命令行中的stdin,而不是pdftk中的stdin(通过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;

}

?>

以上是 如何将变量作为stdin从PHP传递到命令行 的全部内容, 来源链接: utcz.com/qa/414428.html

回到顶部