首页 文章

Cakephp cron作业调用控制器的动作

提问于
浏览
6

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

在合并到 生产环境 服务器之前,我们在开发服务器上进行本地测试 .

我希望每小时调用一个控制器动作,我认为通过我的研究,一个cron工作,我认为这是最好的方法 .


Attempt 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目录(不是app / webroot)中添加了一个名为cron_dispatcher.php的文件,然后从app dir中执行了此命令

php cron_dispatcher.php / controller / action / param

当我通过url调用它时,它仍然没有发生任何事情,但它完美无缺 .


Attempt 2

我尝试创建一个shell(email.php)来调用/ app / vendors / shells /中的操作 .

<?php

class EmailShell extends Shell {

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

}
?>

这样就可以在控制台中成功输出Test

蛋糕邮件主要

但后来我找不到如何调用控制器的动作 . 我试过了

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

我还尝试从shell中的main函数进行调用 .

我试图将控制器包含在$ uses变量中,就像我使用模型一样,但是没有用(并且我觉得这没有意义)

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

可能有一些我遗漏的理论,谢谢


Solution

我将一些方法从控制器移动到模型,我可以从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


编辑:澄清了一些信息并添加了解决方案

2 回答

  • 3

    实际上这是一个非常普遍的问题,也遇到了它 .

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

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

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

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

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

    编辑:

    好问题 .

    采取的步骤:

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

    • 调用shell:现在有问题要调用shell . 一般来说,你不想这样做 . 为什么不?因为shell(任务)可以运行很长时间 . 这就是我们之间使用队列的原因 . 因此,您可以询问队列或让队列向您发送有关已完成操作的消息 . 例如,考虑一个关闭的邮件服务器 . 您必须重试等 . 这不应该在Web请求中,因为用户正在等待响应 .

    • 第三步是从你的cron调用shell,现在这很简单,因为你已经在命令行,所以你可以使用标准调用 .

    无论如何,有一些选项可以从控制器直接调用,但你不应该 . 这篇文章提供了一些非常有趣的见解:CakePHP: Run shell job from controller

    编辑31/08 / '13:有关示例,请参阅CakePHP的事件系统:http://book.cakephp.org/2.0/en/core-libraries/events.html

  • 0

    根据需要做什么,我经常将这些方法保存在我的控制器操作中 . 在操作的顶部,我检查$ _SERVER ['REMOTE_ADDR'] == $ _SERVER ['SERVER_ADDR']以确保只有网站可以调用该操作 . 然后在cron我会卷曲或忘记这个地址 .

    它有它的好处 - 在开发过程中更容易在本地运行(只需在浏览器中输入url),加上运行cli版本的php和apache版本以及请求变量之间存在一些差异(例如,蛋糕无法通过cli获取网站域名/地址,就像您可以作为apache模块运行一样,因此使用html帮助程序的网站绝对链接不起作用) .

相关问题