0

私が達成しようとしているのは、高度にモジュール化されたアプリケーションを作成することです。すべてのサブモジュールで起動する必要があるすべての cron スクリプトに対処する cron スクリプトを作成しようとしています。私が実際にやりたいことは、イベントを作成することです。たとえばrunCron、それが a から起動され、メソッドを使用CControllerしてサブモジュール内から発生したときにそれにフックしonRunCronます。私がやろうとしていることの概要:

Application
|- CronController.php - Raise the event 'RunCron', not knowing which modules will fire after this.
|- Modules
   |- Nodes 
      |- Observe the event 'onRunCron' and run own cron script
   |- Users
      |- Observe the event 'onRunCron' and run own cron script

私が Yii のイベント システムに従って行う必要があると思うのは、イベントを作成し、それをアプリケーション レベルで発生させることです (それはまだ私がやろうとしていることです)。また、サブモジュールからのコールバックをコントローラーのアプリケーション レベルで割り当てる必要があります。サブモジュールが追加/削除されると、アプリケーションを調整する必要があり、モジュラーのように聞こえないため、これは望ましくありません。

このようなイベントを設定し、可能な限りモジュール化するための基本を説明してくれる人はいますか? 私はこれを完全に間違った方法で見ていると思うので。

編集(解決策):

acorncom's answer のおかげで、私は次のシステムを解決することができました。

application.components.CronSingleton

<?php

class CronSingleton extends CApplicationComponent {

    /**
     * Make sure we "touch" the modules, so they are initialised and are able to attach their listeners.
     */
    public function touchModules () {
        $modules = Yii::app()->getModules();

        if (!empty($modules)) {
            foreach ($modules as $name => $module) {
                Yii::app()->getModule($name);
            }
        }
    }

    /**
     * This method should be run to run the cron. It will commense all the procedures in cronjobs
     */
    public function execCron($caller) {
        $this->touchModules();
        $this->onStartCron(new CEvent($caller));
        $this->onRunCron(new CEvent($caller));
        $this->onExitCron(new CEvent($caller));
    }

    /**
     * Raise an event when starting cron, all modules should add their listeners to this event if they would like to fire something before running the cron.
     */
    public function onStartCron ($event) {
        $this->raiseEvent('onStartCron', $event);
    }

    /**
     * Raise an event when running cron, all modules should add their listeners to this event to execute during cron run. Mosty this event should be used.
     */
    public function onRunCron ($event) {
        $this->raiseEvent('onRunCron', $event);
    }

    /**
     * Raise an event when cron exits, all modules should add their listeners to this event when cron exits.
     */
    public function onExitCron ($event) {
        $this->raiseEvent('onExitCron', $event);
    }
}

?>

アプリケーション.コントローラー.CronController

<?php

class CronController extends Controller
{

    public $layout='//layouts/bare';

    public function actionIndex($k) {
        Yii::app()->cron->onStartCron = array($this, 'startcron');
        Yii::app()->cron->onRunCron = array($this, 'runcron');
        Yii::app()->cron->onExitCron = array($this, 'exitcron');
        Yii::app()->cron->execCron($this);
    }

    public function startcron(){
        var_dump('CronController - Starting cron');
    }

    public function runcron(){
        var_dump('CronController - Run cron');
    }

    public function exitcron(){
        var_dump('CronController - Ending cron');
    }
}

?>

application.modules.admin.AdminModule

<?php

class AdminModule extends CWebModule
{
    public function init()
    {
        // this method is called when the module is being created
        // you may place code here to customize the module or the application

        // import the module-level models and components
        $this->setImport(array(
            'admin.models.*',
            'admin.components.*',
        ));

        Yii::app()->cron->onRunCron = array($this, 'runCron');
    }

    public function runCron($event) {
        var_dump('AdminModule - Run cron');
    }

    public function beforeControllerAction($controller, $action)
    {
        if(parent::beforeControllerAction($controller, $action))
        {
            // this method is called before any module controller action is performed
            // you may place customized code here
            return true;
        }
        else
            return false;
    }
}
?>

この「概念実証」セットアップは、まさに私がやりたかったことである、次の結果を出力することに成功しました。

string(30) "CronController - Starting cron"
string(25) "CronController - Run cron"
string(22) "AdminModule - Run cron"
string(28) "CronController - Ending cron"
4

2 に答える 2

1

次のようなことをしたいと思うでしょう (注: これはテストされていませんが、概念的には機能するはずです)。

  1. cron システム用の CApplicationComponent を作成します。アプリケーション コンポーネント (config/main.php ファイルに登録) にすることで、アプリ / モジュール / サブモジュール / コントローラーなどのどこからでもアクセスできるようになります。

  2. cron コンポーネントにイベントの登録/イベントの発火を処理させます。これがどのように機能するかの詳細については、Yii イベント ページを参照してください。注: イベントに関する追加のパラメーターを渡す必要がある場合は、メインの CEvent クラスをサブクラス化する独自のカスタム イベントを作成できます。

  3. モジュールを初期化するときに、イベント ハンドラーとして cron コンポーネントに登録します。

  4. コントローラーに cron コンポーネントへのイベントを発生させます。

1 つの潜在的な落とし穴。モジュールまたはコンポーネントが最初に登録されるかどうかはわかりません (コンポーネントを登録する必要があると思いますが、テストする価値はあります)。イベントをcronコンポーネントに登録しようとしているモジュールの後にcronコンポーネントがロードされている場合は、cronコンポーネントをプリロードすることをお勧めします。それがうまくいかない場合に試すことができる他のハックがいくつかあります (戻ってきて、詳細を尋ねてください)。

ああ、それがどうなるか教えてください!

于 2013-03-05T03:34:51.660 に答える
0

イベントについてyiiのウェブサイトのwikiをチェックしましたか?始めるのに良い場所だと思います。それでも質問がある場合は、私たちがお手伝いします。

于 2013-02-26T17:16:34.440 に答える