2

データベースを集中的に使用する大規模なスクリプトを実行したいのですが、プロセスが完了するまで待つ必要はありません。スクリプトを呼び出してバックグラウンドで実行し、別のページにリダイレクトしたいだけです。

編集:私は、Windows 7 のローカル Zend コミュニティ サーバーで作業しています。プロジェクトも存在するリモート Linux サーバーにアクセスできるので、Linux または Windows でこれを行うことができます。

私はこれを持っています

public function createInstanceAction()
{
    //calls a seperate php process which creates the instance
    exec('php -f /path/to/file/createInstance.php');


    Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('Instance creation process started. This may take up to a few minutes.'));
    $this->_redirect('instances/adminhtml_instances/');
    return;
}

これは完全に機能しますが、magento アプリケーションはプロセスが完了するまでハングアップします。それは私が期待するすべてを行い、時々ファイルにログを記録し、その実行方法に満足しています。今私がやりたいのは、このスクリプトを開始することだけです。コントローラーのアクションはぶらぶらしませんが、代わりにリダイレクトします。私が exec() について学んだことから、上記の exec() を呼び出す方法を次のように変更することで実行できます。

exec('php -f /path/to/file/createInstance.php > /dev/null 2>&1 &');

私はここから取った

"> /dev/null 2>&1 &" を exec 呼び出しに追加すると、期待どおりに待機しませんが、スクリプトは実行されなくなります。誰かが理由を教えてもらえますか?もしそうなら、どうすればこれを機能させることができるか教えてください。

これは許可関連の問題でしょうか?

ありがとう

EDIT : (/dev/null 2>&1 &) を使用して exec 関数を呼び出すと、出力がファイルに記録されることが問題になると想定しています。これは、それをキャンセルするためです。あれは正しいですか?

4

5 に答える 5

2

時間をかけて自分の質問とその答えを完全に理解した後、解決策を準備しました。

あなたの提案、そして質問をするときの私のカジュアルで準備ができていないことを許してくれたすべての人に感謝します。

上記の質問に対する答えは、参照しているオペレーティングシステム、実行しているphpモジュール、さらには実行しているWebサーバーなど、さまざまな要因によって異なります。したがって、質問をもう一度開始する必要がある場合、最初に行うことは、セットアップが何であるかを述べることです。

私は2つの環境でこれを達成したかった:

1.)Zendサーバーコミュニティエディションを実行しているWindows7。2.)Linux(私のOSはLinux odysseus 2.6.32-5-xen-amd64#1 SMP Fri Sep 9 22:23:19 UTC 2011 x86_64)

これを正しく行うために、WindowsまたはLinuxにデプロイするときにどちらの方法でも機能するようにしたかったので、phpを使用してオペレーティングシステムを判別しました。

public function createInstanceAction()
{

    //determines what operating system is Being used 
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
    {
        //This is a windows server

        //call a seperate php process to run independently from the broswer action

        pclose(popen("start php /path/to/script/script.php","r"));

    }
    else
    {
        //assuming its linux, but in fact it simply means its not windows
        // to check for linux specifically use (strtoupper(substr(PHP_OS, 0, 3)) === 'LIN')
        exec('php -f /path/to/file/script.php >/dev/null 2>&1 &');
    }
    //the browser will not hang around for this process to complete, and you can contimue with whatever actions you want.

    //myscript log any out put so i can capture info as it runs
}

つまり、理解したら質問をします。上記を実現する方法はたくさんありますが、これは私の開発環境と本番環境で機能する1つのソリューションにすぎません。

すべての助けに感謝します。

于 2012-07-17T14:07:47.073 に答える
1

私は使用できました:

shell_exec("nohup $command  > /dev/null & echo $!")

たとえば、次の場所$commandです。

php script.php --parameter 1

これでいくつかの奇妙な動作に気付きました。たとえば、mysqlコマンドラインの実行は機能せず、php スクリプトのみが機能するようです。

また、実行cd /path/to/dir && php nohup $command ...も機能しませんchdir()。PHPスクリプト内でコマンドを実行して機能させる必要がありました。

于 2012-07-16T15:21:45.380 に答える
1

createInstance.sh次のように言うと、ラッパースクリプトを書くことができます

#! /bin/bash

trap "" SIGHUP
php -f "$1" > logfile.txt 2>&1 &

次に、PHP 内からスクリプトを呼び出します。

exec('bash "/path/to/file/createInstance.sh"');

これにより、新しい php プロセスがスクリプトから最も瞬時に切り離されます。それでも解決しない場合は、SIGHUP の代わりに SIGABRT、SIGTERM、または SIGINT を使用してみてください。送信されるシグナルが正確にはわかりません。

于 2012-07-15T14:44:49.557 に答える
1

PHP 開く

ドキュメントから(これは、そのプロセスが機能している間に他のことを行うのに役立つはずです。現在のPHPプロセスを閉じると、開いているプロセスが強制終了されるかどうかはわかりません):

/* Add redirection so we can get stderr. */
$handle = popen('/path/to/executable 2>&1', 'r');
echo "'$handle'; " . gettype($handle) . "\n";
$read = fread($handle, 2096);
echo $read;
pclose($handle);

解決策 2: ブラウザをだまして接続を閉じる (ブラウザが関与していると仮定して):

ob_start();
?><html><!--example html body--></html><?php
$strContents=ob_get_clean(); 

header("Connection: Close");
header("Content-encoding: none");//doesn't work without this, I don't know why:(

ignore_user_abort(true);

header("Content-type: text/html");
header("Content-Length: ".strlen($strContents));
echo $strContents;

flush();
//at this point a real browser would close the connection and finish rendering; 
//crappy http clients like some curl implementations (and not only) would wait for the server to close the connection, then finish rendering/serving results...:(

//TODO: add long running operations here, exec, or whatever you have.
于 2012-07-15T14:34:12.307 に答える
0

Zend Server に含まれている PHP 実行可能ファイルが原因で、バックグラウンドでスクリプトを実行しようとすると (exec でアンパサンド & 演算子を使用して) 失敗するようです。

標準の PHP 実行可能ファイルを使用してこれをテストしたところ、問題なく動作しました。これは、Zend Server に同梱されているバージョンと関係がありますが、何が起こっているのかを突き止めるための限られた試みでは何も明らかになりませんでした.

于 2012-08-15T20:53:40.150 に答える