سؤال

لقد حصلت على السيناريو PHP الذي يحتاج إلى الاحتجاج شيل ولكن لا تهتم الإخراج.قذيفة النصي عددا من الصابون المكالمات بطيئة كاملة ، لذلك أنا لا أريد أن تبطئ PHP طلب في حين أنه ينتظر الرد.في الواقع, PHP الطلب يجب أن تكون قادرة على الخروج من دون إنهاء عملية قذيفة.

لقد بحثت في مختلف exec(), shell_exec(), pcntl_fork(), ، وما إلى ذلك.وظائف, ولكن أيا منها لا يبدو أنها تقدم بالضبط ما أريد.(أو إذا فعلوا ذلك ، ليس من الواضح لي كيف.) أي اقتراحات ؟

هل كانت مفيدة؟

المحلول

إذا كان "لا يهتمون الانتاج"، لا يمكن أن يسمى إكسيك إلى البرنامج النصي مع & إلى خلفية هذه العملية؟

تعديل - يمكنك دمج ما علق @ AdamTheHut لهذا المنصب، ويمكنك إضافة هذه إلى دعوة إلى exec:

" > /dev/null 2>/dev/null &"

وهذا سيتم توجيه كل من stdio (> أولا) وstderr (2>) ل/dev/null وتعمل في الخلفية.

وهناك طرق أخرى للقيام بنفس الشيء، ولكن هذا هو أبسط لقراءة.


وبديل إلى ما سبق المزدوج إعادة توجيه:

" &> /dev/null &"

نصائح أخرى

اعتدت في لهذا, كما بدأت فعلا مستقلة العملية.

<?php
    `echo "the command"|at now`;
?>

لجميع مستخدمي ويندوز: لقد وجدت وسيلة جيدة لتشغيل برنامج نصي PHP غير متزامن (في الواقع يعمل مع كل شيء تقريبا)

.

وأنها تقوم على popen () وpclose () أوامر. ويعمل بشكل جيد على حد سواء على ويندوز ويونكس.

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

ورمز الأصلي من: http://php.net/manual/en/function.exec.php # 86329

في لينكس يمكنك القيام بما يلي:

$cmd = 'nohup nice -n 10 php -f php/file.php > log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);

وهذا سيتم تنفيذ الأمر في الأمر برومبتي ثم يعود فقط PID، والتي يمكن أن تحقق لل> 0 للتأكد من أنه يعمل.

وهذا السؤال هو مماثل: هل PHP دينا خيوط

فب-تنفيذ واحد في خلفية عملية لديه بعض الاقتراحات الجيدة . أعتقد الألغام هو جيد جدا، ولكن أنا منحاز:)

في لينكس، يمكنك البدء في عملية في موضوع مستقل جديد بإلحاق العطف في نهاية الأمر

mycommand -someparam somevalue &

في Windows، يمكنك استخدام "بدء" القيادة DOS

start mycommand -someparam somevalue

الطريق الصحيح(!) للقيام بذلك

  1. شوكة()
  2. setsid()
  3. execve()

شوكة من شوك ، setsid قل العملية الحالية لتصبح على درجة الماجستير واحد (أي الأم) ، execve أخبر عملية الاستدعاء إلى محل يسمى واحد.حتى أن الأم يمكن أن تترك دون التأثير على الطفل.

 $pid=pcntl_fork();
 if($pid==0)
 {
   posix_setsid();
   pcntl_exec($cmd,$args,$_ENV);
   // child becomes the standalone detached process
 }

 // parent's stuff
 exit();

وأنا استخدم هذا ...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

و(حيث PHP_PATH هو CONST محددة مثل define('PHP_PATH', '/opt/bin/php5') أو ما شابه ذلك)

ويمر في الحجج عبر سطر الأوامر. لقراءتها في PHP، انظر ARGV .

والطريقة الوحيدة التي وجدت أن عملت حقا بالنسبة لي هو:

shell_exec('./myscript.php | at now & disown')

وكما أنني وجدت symfony لعملية مكون مفيدة لذلك.

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
// ... run process in background
$process->start();

// ... do other things

// ... if you need to wait
$process->wait();

// ... do things after the process has finished

وانظر كيف يعمل في تقريرها جيثب الريبو .

استخدم يخرج أولا اسمه.

#!/bin/sh
mkfifo trigger
while true; do
    read < trigger
    long_running_task
done

وبعد ذلك كلما كنت تريد أن تبدأ مهمة طويلة قيد التشغيل، ببساطة كتابة سطر جديد (توصيل nonblocking إلى ملف الزناد.

وطالما الإدخال أصغر من PIPE_BUF وانها عملية write() واحدة، يمكنك كتابة الحجج في FIFO ويكون لهم كما تظهر $REPLY في البرنامج النصي.

يمكنك أيضا تشغيل PHP النصي شيطان أو cronjob: #!/usr/bin/php -q

ودون انتظار الاستخدام، يمكنك استخدام proc_open() مثل هذا :

    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w"),
        2 => array("pipe", "w")    //here curaengine log all the info into stderror
    );
    $command = 'ping stackoverflow.com';
    $process = proc_open($command, $descriptorspec, $pipes);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top