210

シェルスクリプトを呼び出す必要があるが、出力についてはまったく気にしないPHPスクリプトがあります。シェルスクリプトは多数のSOAP呼び出しを行い、完了に時間がかかるため、応答を待機している間はPHP要求の速度を落としたくありません。実際、PHPリクエストは、シェルプロセスを終了せずに終了できる必要があります。

exec()、、、などshell_exec()のさまざまな機能を調べましたpcntl_fork()が、どれも私が望むものを正確に提供していないようです。(または、もしそうなら、その方法は私にはわかりません。)何か提案はありますか?

4

13 に答える 13

234

「出力を気にしない」場合は、スクリプトのexecを呼び出して&、プロセスをバックグラウンドで実行できませんでしたか?

編集-@ AdamTheHutがこの投稿にコメントした内容を組み込んで、これを次の呼び出しに追加できますexec

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

stdioこれにより、 (first >)とstderr2>)の両方がリダイレクトさ/dev/nullれ、バックグラウンドで実行されます。

同じことをする方法は他にもありますが、これが最も読みやすい方法です。


上記のダブルリダイレクトの代替手段:

" &> /dev/null &"
于 2008-10-21T16:08:03.283 に答える
57

実際に独立したプロセスを開始しているので、これにatを使用しました。

<?php
    `echo "the command"|at now`;
?>
于 2008-10-21T22:20:47.040 に答える
39

すべての Windows ユーザーへ: 非同期 PHP スクリプトを実行する良い方法を見つけました (実際には、ほとんどすべてで動作します)。

popen() および pclose() コマンドに基づいています。また、Windows と Unix の両方でうまく動作します。

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

于 2016-10-25T15:12:07.660 に答える
23

Linux では、次のことができます。

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

これにより、コマンド プロンプトでコマンドが実行され、PID が返されます。この PID が 0 を超えているかどうかをチェックして、機能していることを確認できます。

この質問は似ています: PHP にはスレッドがありますか?

于 2008-10-21T22:27:26.450 に答える
13

php-execute-a-background-processには、いくつかの良い提案があります。私はかなり良いと思いますが、私は偏っています:)

于 2008-10-21T22:29:26.537 に答える
6

Linux では、コマンドの最後にアンパサンドを追加することで、新しい独立したスレッドでプロセスを開始できます。

mycommand -someparam somevalue &

Windows では、"start" DOS コマンドを使用できます。

start mycommand -someparam somevalue
于 2008-10-21T22:46:46.720 に答える
6

これを使った...

/** 
 * 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を参照してください。

于 2010-07-19T20:25:46.317 に答える
6

それを行う正しい方法(!)は

  1. フォーク()
  2. セットid()
  3. execve()

fork フォーク、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();
于 2008-11-14T15:31:56.447 に答える
4

私にとって本当にうまくいったことがわかった唯一の方法は次のとおりです。

shell_exec('./myscript.php | at now & disown')
于 2012-02-08T18:11:32.177 に答える
2

PHP スクリプトをデーモンまたはcronjobとして実行することもできます。#!/usr/bin/php -q

于 2008-11-07T07:33:53.567 に答える
1

名前付き fifo を使用します。

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

その後、実行時間の長いタスクを開始するときはいつでも、単純に改行を書き込みます (トリガー ファイルにノンブロッキング)。

入力がより小さくPIPE_BUF、それが単一のwrite()操作である限り、引数を fifo に書き込ん$REPLYで、スクリプトのように表示させることができます。

于 2008-11-14T15:47:02.207 に答える