PHP komut satırında stdin'i gibi değişkenler geçmek için nasıl

3 Cevap php

Ben bir PDF formu ve çıkış kullanıcıya birleştirilmiş PDF bir XFDF'den birleştirmek için pdftk uygulamasını kullanan bir PHP komut dosyası yazmak çalışıyorum. Pdftk belgelerine göre, ben stdin via form verilerini geçmek ve stdout akışı PDF çıkış olabilir. Komut satırından PDFTK kullanmak için normal dosya değil-stream yoludur:

pdftk blankform.pdf fill_form formdata.xfdf output filledform.pdf

Komut satırında akışlarını kullanmak için, girmek istiyorum:

pdftk blankform.pdf fill_form - output -

Ben birkaç sorun var:

1) stdout bir xfdf dosyasını kullanarak (yerine stdin) şöyle aracılığıyla çıktı dönmek PDFTK aldık:

    exec("pdftk blankform.pdf fill_form formdata.xfdf output -", $pdf_output);
    file_put_contents("filledform.pdf",$pdf_output);

Ama oluşturur pdf Adobe Reader göre, bozuk ve bir metin editörü ile dosyanın hızlı bir gözetleme en azından, onlar olması gerektiği satır sonlarını ayarlama değil, gösterir. Ben bunu bir dosyaya çıktı ve pdf metin editörü ince görünüyor pdftk tarafından oluşturulan özdeş bir PDF var, bu yüzden o kadar kötü, veri çıkışı oluyor Pdftk değil biliyorum.

2) Ben bana yaşam için ben pdftk benim girdi olarak bu akış kullanın böylece PHP stdin akışı ayarlamak için nasıl anlamaya olamaz. Ben PHP belgelerinde okuyorum ne, stdin, yalnızca-okunur, bu nedenle nasıl bir şey hiç o akışı içine alır?

İdeal olarak, bu gerçekten basit tutmak ve proc_open() kullanmaktan kaçınmak istiyorum. Ben bu işlevi kullanmak için çalıştı ve çok sucessful değildi, değil işlevi adlı, muhtemelen benim hatam olduğunu, ama gerçekten benim goller doğrusu ben ihtiyaç duymayan sağlam fonksiyonlarını kullanarak kaçındığınız yeterince basittir.

İdeal benim kod gibi bir şey olacaktır:

 $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 -);

Sadece bir mezartaşı yukarıya, o komut satırında gerçek xml dize koymak mümkündür, ama bu ile very güvenilmez sonuçlar yaşadım.

Edit

Çok yardımıyla, şimdi benim asıl soru "nasıl olabilir boru PHP bir komut satırı yürütme değişken" olduğunu anlıyoruz. Görünüşe proc_open gitmek için en iyi yoldur, ya da en azından en basit. Bu anlamaya sonsuza kadar götürdü ve Google'da araştırma diğerleri mücadele edilebilir anlaşılacağı beri, ben özellikle benim sorun için çalıştı kodunu göndeririz beri:

$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;
}

3 Cevap

Ben size ulaşmak için çalışıyoruz ne emin değilim. Sen URL php :/ / stdin stdin okuyabilirsiniz. Ama bu PHP komut satırında değil (exec) aracılığıyla pdftk dan itibaren stdin bulunuyor.

Ama ben proc_open() için 1 vereceğiz


<?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;
}
?>

Ben giriş fdf göndermek için kullandığınız yöntem, böyle bir şey olur:

$command = "echo '$fdf_data' | pdftk $infile fill_form - output $outfile"; shell_exec($command);

Ama sizin gibi, ben pdftk gelen Stdout'a güvenilir çıktı almak mümkün değilim. Nedenini bilmiyorum.

1) Neden standart dışarı çıktı alan ve daha sonra bir dosya içine malzeme koyarak? Neden sadece, dosyaya dökümü Pdftk değil yani

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

2) kullanın proc_open(). Eğer fonksiyonu ile herhangi bir sorunları göndermek için çekinmeyin.