Cakephp cron作业调用控制器的动作 [英] Cakephp cron job to call a controller's action

查看:421
本文介绍了Cakephp cron作业调用控制器的动作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我几个月前开始使用CakePHP(1.2)来为公司的应用程序添加小功能,我不太熟悉它。



我们测试然后在开发服务器上,然后合并到生产服务器。



我想要每小时调用一个控制器操作,我假设是最好的方法






尝试1 b

阅读完这些之后,



http://bakery.cakephp.org/articles/mathew_attlee/2006/12/05/calling-controller-从命令行和命令行执行操作



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



我可以实现没有错误的东西,但是不执行动作。



根据这些例子,我添加了一个名为cron_dispatcher的文件。 php在我的应用程序目录(不是app / webroot),然后从应用程序dir执行此命令


php cron_dispatcher.php / controller / action / param


仍然没有发生任何事情,但当我通过URL调用它时工作完美。






尝试2



我尝试创建一个shell(email.php)将调用/ app / vendors / shells /.

 <?php 

class EmailShell extends Shell {

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

}
?>

使用

在控制台中成功输出Test

< blockquote>

蛋糕电子邮件主


但是我找不到如何调用控制器的操作。我尝试过


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




我也试图从一个不同的函数调用,而不是shell中的main。



包括控制器在$ uses变量,因为我会用一个模型,但是没有工作(这是没有意义的我认为)



我不认为创建一个任务是解决方案,因为我不想复制sendEmails函数,因此为什么我正在寻找一种方法,只是从shell或任何调用控制器的操作!



可能有一些理论我缺少,谢谢



我将一些方法从控制器移动到模型,我可以从shell调用它们。

  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






一些信息并添加了解决方案

解决方案

这是一个很常见的问题,

控制器正在决定如何处理请求并启动该任务。在这种情况下,不需要一个控制器,因为你有一个shell任务,任务已经清楚。



知道这一点,调用控制器没有意义方法。



重新思考你的选择,是的,这是一个相当困难的。例如,您可能决定发送电子邮件是一个业务逻辑步骤,因此它应该在模型中。另一个选择是将它完全分开(这是我们最喜欢的)。



在这种情况下,您将必须创建一个队列,您放入所有电子邮件发送。这是一个好的设计,因为你知道控制器中的逻辑量下降,它是分开的。这样您就可以获得电子邮件服务。



例如,您可以要求服务发送新用户邮件。然后你添加User对象到它,它应该处理自己。这样你甚至可以扩展,因为你的服务可能是外包,你可以扩展服务等多个服务器等。



编辑:



好问题。



采取的步骤:


  1. 首先集中发送电子邮件过程。所以选择一个位置放在哪里。您可以决定:添加发送电子邮件到队列或直接调用服务。例如,您可以添加shell任务来发送电子邮件。


  2. 调用shell:现在您有调用shell的问题。一般你不想。为什么不?因为shell(任务)可能运行很长时间。所以这就是为什么我们使用之间的队列。所以你可以问队列或让队列消息你做了什么。例如,考虑一个失败的邮件服务器。您必须重试等。这不应该在网络请求中,因为用户正在等待响应。


  3. 第三步是从您的cron调用shell ,现在很容易,因为你已经在命令行,所以你可以使用标准调用。


无论如何,选项来从控制器直接调用,但你不应该。这篇文章提供了一些非常有趣的见解:
CakePHP:从控制器运行shell作业



编辑31/08 / '13:查看CakePHP的事件系统也有一些例子: http://book.cakephp.org/2.0/en/core-libraries/events.html


I started to use CakePHP (1.2) a few months ago to add small features to the company's application and I'm not too familiar with it.

We test locally then on a development server before merging to a production server.

I want a controller action to be called every hour with what I assumed to be the best way to do this through my researches, a cron job.


Attempt 1

After reading these,

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

I could implement something without errors, but the action is not executed.

Based on these examples, I added a file named cron_dispatcher.php in my app directory (not app/webroot) and then did this command from the app dir

php cron_dispatcher.php /controller/action/param

Still nothing happened but it works perfect when I call it through the url.


Attempt 2

I tried creating a shell (email.php) that would call the action in /app/vendors/shells/.

<?php

class EmailShell extends Shell {

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

}
?> 

This successfully outputs Test in the console using

cake email main

but then I cannot find how to call the controller's action. I have tried

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

I have also tried to make the call from a different function than the main in the shell.

I have tried to include the controller in the $uses variable as I would with a model but that didn't work (and it doesn't make sense I think)

I don't think creating a task is the solution either as I don't want to duplicate the sendEmails function hence why I'm looking for a way to just call the controller's action from a shell or whatever!

There is probably some theory I'm missing, thanks


Solution

I moved some methods from the controller to a model and I was able to call them from a shell.

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();
        //...
    }
}

This link helped http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html


edit : clarified some of the information and added the solution

解决方案

It is a quite common issue actually, ran into it also.

A controller is deciding how to handle a request and starting that task. In this case there is no need for a controller since you have a shell task, the task is already clear.

Knowing that, it does not make sense to call a controller method.

So rethink your options, and yes this is a quite difficult one. For example you might decide that sending the e-mail is a business logic step so it should be in the model. Another option is to separate it totally (that's what we like most).

In that case you will have to create a queue where you put in all e-mails to send. That is a good design since you then know the amount of logic in the controller goes down and it is separated. That way you get an e-mail service.

For example you could ask the service to send a "new user" mail. Then you add the User object to it and it should handle itself. That way you can even scale since your service could be for example outsourced, you could expand multiple servers on the service etc.

Edit:

Good questions.

Steps to take:

  1. Centralize the "sending e-mail" process first. So choose one location where to put it. The you can decide: Add to send e-mail to a queue or call the service directly. For example you could add shell task for sending the e-mails.

  2. Call the shell: Now you have the problem to call the shell. In general you don't want to. Why not? Because a shell (a task) could run for a long time. So that's why we use queues in between. So you can ask the queue or let the queue message you that something is done. For example think about a mail server which is down. You have to retry etc. That should not be in a web request because the user is waiting for response.

  3. Third step is to call the shell from your cron, now that's easy since you are already on the command line so you could use standard calls.

Anyhow, there are options to do a direct call from a controller but you should not. This post gives some very interesting insights: CakePHP: Run shell job from controller

Edit 31/08/'13: See the events system of CakePHP also for some examples: http://book.cakephp.org/2.0/en/core-libraries/events.html

这篇关于Cakephp cron作业调用控制器的动作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆