6

私は数ヶ月前にCakePHP(1.2)を使い始めて、会社のアプリケーションに小さな機能を追加しましたが、あまり慣れていません。

次に、本番サーバーにマージする前に、開発サーバーでローカルにテストします。

コントローラーアクションを1時間ごとに呼び出して、私の調査でこれを行うための最良の方法であると想定したcronジョブを使用したいと思います。


試行1

これらを読んだ後、

http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-actions-from-cron-and-the-command-line

http://book.cakephp.org/1.2/en/view/110/Creating-Shells-Tasks

エラーなしで何かを実装できましたが、アクションは実行されません。

これらの例に基づいて、(app / webrootではなく)appディレクトリにcron_dispatcher.phpという名前のファイルを追加し、appdirからこのコマンドを実行しました。

php cron_dispatcher.php / controller / action / param

それでも何も起こりませんでしたが、URLを介して呼び出すと完璧に機能します。


試行2

/ app / vendors / shells /にアクションを呼び出すシェル(email.php)を作成してみました。

<?php

class EmailShell extends Shell {

    public function main() {
        $this->out('Test');
    }

}
?> 

これにより、を使用してコンソールにテストが正常に出力されます。

ケーキメールメイン

しかし、コントローラーのアクションを呼び出す方法が見つかりません。私が試してみました

$ this-> requestAction('/ controller / action');

また、シェルのメインとは異なる関数から呼び出しを試みました。

モデルの場合と同じように$uses変数にコントローラーを含めようとしましたが、機能しませんでした(そして、私が思うに意味がありません)。

sendEmails関数を複製したくないので、タスクを作成することも解決策ではないと思います。そのため、シェルなどからコントローラーのアクションを呼び出す方法を探しているのはなぜですか。

おそらく私が見逃している理論がいくつかあります、ありがとう


解決

いくつかのメソッドをコントローラーからモデルに移動し、シェルからそれらを呼び出すことができました。

App::import('Component', 'Email');

class SendMemosShell extends Shell {

    var $uses = array(
        'Memo',
    );

    public function main() {

    }

    public function sendEmails () {
        $this->Email =& new EmailComponent(null);
        $memoList = $this->Memo->getMemos();
        //...
    }
}

このリンクは http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.htmlに役立ちました


編集:いくつかの情報を明確にし、解決策を追加しました

4

2 に答える 2

3

それは実際には非常に一般的な問題であり、それに遭遇しました。

コントローラは、リクエストの処理方法を決定し、そのタスクを開始しています。この場合、シェルタスクがあるため、コントローラーは必要ありません。タスクはすでにクリアされています。

それを知っているので、コントローラーメソッドを呼び出すことは意味がありません。

だからあなたの選択肢を考え直してください、そしてそうです、これは非常に難しいものです。たとえば、電子メールの送信はビジネスロジックのステップであるため、モデルに含める必要があると判断する場合があります。別のオプションは、それを完全に分離することです(それが私たちが最も好きなものです)。

その場合、送信するすべての電子メールを入れるキューを作成する必要があります。これは、コントローラーのロジックの量が減少し、分離されていることがわかるため、優れた設計です。そうすれば、電子メールサービスを利用できます。

たとえば、「新しいユーザー」のメールを送信するようにサービスに依頼できます。次に、Userオブジェクトを追加すると、それ自体が処理されます。そうすれば、たとえばサービスをアウトソーシングしたり、サービス上の複数のサーバーを拡張したりできるため、拡張することもできます。

編集:

良い質問です。

実行する手順:

  1. 最初に「電子メールの送信」プロセスを一元化します。したがって、配置する場所を1つ選択してください。あなたは決めることができます:キューに電子メールを送るために追加するか、サービスを直接呼び出すために。たとえば、電子メールを送信するためのシェルタスクを追加できます。

  2. シェルを呼び出す:シェルを呼び出す問題が発生しました。一般的に、あなたはしたくありません。なぜだめですか?シェル(タスク)が長時間実行される可能性があるためです。そのため、間にキューを使用します。したがって、キューに問い合わせるか、キューに何かが行われたことを通知させることができます。たとえば、ダウンしているメールサーバーについて考えてみます。再試行する必要があります。ユーザーが応答を待っているため、これはWebリクエストには含まれないはずです。

  3. 3番目のステップは、cronからシェルを呼び出すことです。これは、すでにコマンドラインを使用しているため、標準の呼び出しを使用できるため、簡単です。

とにかく、コントローラーから直接呼び出しを行うオプションがありますが、そうすべきではありません。この投稿はいくつかの非常に興味深い洞察を提供します: CakePHP:コントローラーからシェルジョブを実行します

編集31/08/'13:いくつかの例については、CakePHPのイベントシステムも参照してください:http://book.cakephp.org/2.0/en/core-libraries/events.html

于 2012-06-29T17:42:59.053 に答える
0

何をする必要があるかに応じて、私はこれらのメソッドをコントローラーアクションに保持することがよくあります。アクションの先頭で、$ _ SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']をチェックして、Webサイトのみがアクションを呼び出すことができることを確認します。次に、cronで、このアドレスをカールまたは取得します。

これには利点があります-開発中にローカルで実行するのが簡単です(ブラウザにURLを入力するだけです)。さらに、リクエスト変数だけでなく、phpのcliバージョンとapacheバージョンの実行にはいくつかの違いがあります(たとえば、cakeは取得できません) Apacheモジュールとして実行できるようなCLIを介したWebサイトのドメイン/アドレスであるため、htmlヘルパーを使用したWebサイトへの絶対リンクは機能しません)。

于 2012-06-30T13:16:44.273 に答える