簡體   English   中英

無法使用PHP執行外部進程

[英]Can't execute external process with PHP

我有以下代碼

function generate_pdf() {

        $fdf_data_strings = $this->get_hash_for_pdf();
        #$fdf_data_names   = array('49a' => "yes");
        $fdf_data_names = array();
        $fields_hidden    = array();
        $fields_readonly  = array();
        $hud_pdf = ABSPATH.'../pdf/HUD3.pdf';

        $fdf= forge_fdf( '',
                 $fdf_data_strings,
                 $fdf_data_names,
                 $fields_hidden,
                 $fields_readonly );

        /*  echo "<pre>";
            print_r($fdf);
            echo "</pre>";
            die('');
        */

        $fdf_fn= tempnam( '.', 'fdf' );
        $fp= fopen( $fdf_fn, 'w' );
        if( $fp ) {
          fwrite( $fp, $fdf );
            //$data=fread( $fp, $fdf );
         // echo $data;
          fclose( $fp );


          header( 'Content-type: application/pdf' );
          header( 'Content-disposition: attachment; filename=settlement.pdf' ); // prompt to save to disk

          passthru( 'pdftk HUD3.pdf fill_form '. $fdf_fn.' output - flatten');

          unlink( $fdf_fn ); // delete temp file

        }
        else { // error
          echo 'Error: unable to open temp file for writing fdf data: '. $fdf_fn;
        }
    }
}

它有什么問題嗎?

問題是,我已經安裝了pdftk

跑到whereis pdftk給我'/usr/local/bin/pdftk'

實際檢查了位置,pdftk在那個位置..

使用終端,如果我運行pdftk --version或任何其他命令,它運行

如果我使用像passthru('/usr/local/bin/pdftk --version')這樣的PHP, passthru('/usr/local/bin/pdftk --version')顯示任何內容

如果我使用php喜歡system("PATH=/usr/local/bin && pdftk --version"); 它說'/usr/local/bin /pdftk :there is no directory of file '

當我運行這個函數腳本時,提示文件下載彈出,但是當我保存它時,nothng被保存,

我已經檢查權限,該文件夾並改變了它0755, 0766, 0777, 0666我已經嘗試了所有,nothng作品

3天,我正在努力克服它,我也問過這個問題,但無法弄清楚到底是怎么回事。

在我撞牆之前,有人可以幫助我嗎?

pasthru函數不通過shell執行程序。

將准確的路徑傳遞給passthru命令。

例如

passthru( '/usr/local/bin/pdftk HUD3.pdf fill_form '. $fdf_fn.' output - flatten');

或者passthru('/ usr / local / bin / pdftk'。$ hud_pdf。'fill_form'。$ fdf_fn。'output - flatten');

如果仍然無法使用<?php passthru("/path/to/pdftk --help"); ?> <?php passthru("/path/to/pdftk --help"); ?>其中/ path / to / pdftk是您返回的路徑,由哪個或哪個位置確保路徑正確。

如果路徑正確,那么問題可能與您告訴pdftk使用的臨時目錄上的權限或者關於apache用戶的pdftk二進制文件的權限有關。

如果這些權限很好,你可以驗證pdftk是從php啟動但是從運行命令中掛起,然后可能可以嘗試這里列出的解決方法。

關於passthru的進一步文檔是可用的passthru PHP手冊

作為旁注, putenv php函數用於設置環境變量。

例如putenv('PATH='.getenv('PATH').':.');

所有3個PHP函數:exec(),system()和passthru()執行外部命令,但不同之處是:

  • exec():返回命令的最后一行輸出並且不刷新任何內容。
  • shell_exec():返回命令的整個輸出並且不刷新任何內容。
  • system():返回命令的最后一行輸出,並嘗試在輸出的每一行之后刷新輸出緩沖區。
  • passthru():不返回任何內容並傳遞結果輸出​​而不會干擾瀏覽器,尤其在輸出為二進制格式時非常有用。

另請參閱PHP exec vs-system vs passthru SO Question

這些函數的實現位於exec.c並使用popen。

我有同樣的問題,經過大量實驗后,這是有效的:

function InvokePDFtk($pdf_tpl, $xfdf,$output){

        $params=" $pdf_tpl fill_form $xfdf output $output flatten 2>&1";

        $pdftk_path=exec('/usr/bin/which /usr/local/bin/pdftk');

        $have_pdftk= $pdftk_path=='/usr/local/bin/pdftk' ;

        $pdftk_path=$have_pdftk  ? $pdftk_path  : 'pdftk ';

        exec($pdftk_path.$params,$return_var);

        return  array('status'=> $have_pdftk,
                     'command' =>$pdftk_path.$params, 'output'=>$return_var);
    }

希望這可能會給你一些見解。 (根據您的需要改變)

完成Appleman的回答,這三個函數可以被認為是危險的,因為它們允許您使用php執行程序,因此如果您不小心使用,攻擊者會利用您的一個腳本。 因此,在許多想要安全的php配置中,它們被禁用。

所以你應該檢查你的php.ini(和任何php配置文件)中的disable_functions指令,看看你使用的功能是否被禁用。

也許你應該將fclose保留在if語句之外,確保你將它指向正確的文件! :)

你的網絡服務器是否被chrooted? 嘗試將可執行文件放入服務器可查看的目錄中。

使用安全模式四處游走並明確檢查您的Web服務器日志文件,通常在:

/var/log/apache2/error.log

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM