Невозможно выполнить внешний процесс с помощью 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 или любую другую команду, она запускается

если я использую 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 '

когда я запускаю этот функциональный сценарий, появляется запрос на загрузку файла, но когда я сохраняю его, ничего не сохраняется,

я проверил разрешение для этой папки и изменил его 0755, 0766, 0777, 0666 я перепробовал все, ничего не работает

В течение 3 дней я пытаюсь преодолеть это, и я тоже задал вопрос по этому поводу, но не могу понять, что, черт возьми, со мной происходит.

Может ли кто-нибудь помочь мне, прежде чем я ударись головой об стену?


person Zaffar Saffee    schedule 24.03.2012    source источник
comment
Как насчет: системы (ПУТЬ = / usr / local / bin / pdftk --version);   -  person Milan Babuškov    schedule 25.03.2012
comment
Что касается: / usr / local / bin / pdftk --version, возможно, версия выводится на stderr, а не на stdout, поэтому вы ничего не получаете. А также загляните в error.log веб-серверов.   -  person Milan Babuškov    schedule 25.03.2012
comment
если вы запрашиваете систему (PATH = / usr / local / bin / pdftk --version 2 ›& 1), то результатом будет sh: pdftk: command not found   -  person Zaffar Saffee    schedule 25.03.2012
comment
где это дает / пользователь или / usr? Я предполагаю, что это опечатка в вопросе, но, возможно, у вас есть какие-то особые настройки.   -  person Milan Babuškov    schedule 25.03.2012
comment
его / usr / я проверил снова ..   -  person Zaffar Saffee    schedule 25.03.2012
comment
Можете ли вы попробовать запустить в командной строке php -r "passthru('/usr/local/bin/pdftk --version');"?   -  person houbysoft    schedule 27.03.2012
comment
@houbysoft, нет, я не могу запустить эту команду, я ввел ту же команду, которую вы вставляете здесь, и нажмите Enter, она перейдет к ›знаку .. и никаких результатов не будет ..   -  person Zaffar Saffee    schedule 28.03.2012
comment
@NewBee: ты, наверное, забыл последнюю цитату?   -  person houbysoft    schedule 28.03.2012
comment
попробовал сейчас, появляется ошибка: php, команда не найдена, я набираю как 'php -r passthru (' / usr / local / bin / pdftk --version ')'   -  person Zaffar Saffee    schedule 28.03.2012
comment
Вы смотрели error_log apache?   -  person mike_hornbeck    schedule 06.06.2012


Ответы (6)


Функция pasthru не выполняет программу через оболочку.

Передайте точный путь в команду passthru.

E.g.

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"); ?>, где / path / to / pdftk - это ваш путь, возвращенный тем или иным, чтобы убедиться, что путь правильный.

Если путь правильный, проблема может быть связана с разрешениями либо для временного каталога, который вы указываете pdftk, либо с разрешениями на двоичный файл pdftk в отношении пользователя apache.

Если с этими разрешениями все в порядке, вы можете проверить, что pdftk запускается с php, но зависает при выполнении вашей команды, тогда вы можете попробовать обходной путь, указанный в здесь.

Дополнительная документация по passthru доступна passthru PHP Manual.

В качестве примечания: для установки переменных среды используется функция php putenv.

E.g. putenv('PATH='.getenv('PATH').':.');

Все 3 функции PHP: exec (), system () и passthru () выполняют внешнюю команду, но различия заключаются в следующем:

  • exec (): возвращает последнюю строку вывода команды и ничего не сбрасывает.
  • shell_exec (): возвращает весь вывод команды и ничего не сбрасывает.
  • system (): возвращает последнюю строку вывода команды и пытается очистить буфер вывода после каждой строки вывода по ходу.
  • passthru (): ничего не возвращает и передает результирующий вывод без вмешательства в браузер, что особенно полезно, когда вывод находится в двоичном формате.

Также см. Вопрос PHP exec vs-system vs passthru SO.

Реализация этих функций находится по адресу exec. c и использует popen.

person Appleman1234    schedule 26.03.2012

У меня была такая же проблема, и это работает после множества экспериментов:

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

надеюсь, это может дать вам некоторое представление. (измените в соответствии с вашими потребностями)

person sakhunzai    schedule 30.03.2012

Завершая ответ Appleman, эти 3 функции можно считать опасными, потому что они позволяют вам выполнять программу с использованием php, таким образом, злоумышленник, который использовал один из ваших скриптов, если вы недостаточно осторожны. Поэтому во многих конфигурациях php, которые хотят быть в безопасности, они отключены.

Поэтому вам следует проверить директиву disable_functions в своем php.ini (и любом файле конфигурации php) и посмотреть, отключена ли используемая вами функция.

person grifos    schedule 29.03.2012

Возможно, вам следует исключить fclose из оператора if, убедитесь, что он направлен в правильный файл! :)

person Jahanzeb Khan    schedule 02.04.2012

Ваш веб-сервер привязан к корневому каталогу? Попробуйте поместить исполняемый файл в каталог, доступный для просмотра сервером.

person Mason Heller    schedule 02.04.2012

Поиграйте с безопасным режимом и обязательно проверьте файл журнала веб-сервера, обычно в:

/var/log/apache2/error.log
person Eugene van der Merwe    schedule 02.04.2012