2012-06-29 48 views
6

几个月前我开始使用CakePHP(1.2)为公司的应用程序添加小功能,我对此不太熟悉。Cakephp cron作业调用控制器的动作

我们在合并到生产服务器之前先在开发服务器上进行本地测试。

我想要一个控制器动作,每小时调用一次我认为是通过我的研究,一个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

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

基于这些例子中,我添加了一个名为cron_dispatcher.php文件在我的应用程序目录(而不是应用程序/ Web根目录),然后从应用程序目录

PHP cron_dispatcher.php /控制器/动作做这个命令/参数

仍然没有发生,但它通过网址调用它时,完美。


尝试2

我试图创建一个壳(email.php),将调用/应用/销售商/壳动作/。

<?php 

class EmailShell extends Shell { 

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

} 
?> 

这成功地输出测试使用

蛋糕电子邮件主要

控制台但我找不到如何调用控制器的动作。我试过

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

我也尝试使用与shell中的main函数不同的函数进行调用。

我曾尝试以包括$控制器使用变量,我会一个模型,但没有工作(和它没有任何意义,我认为)

我不认为创建任务是解决方案,因为我不想复制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


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

回答

3

它实际上是一个相当普遍的问题,碰到了也。

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

知道了,调用控制器方法没有任何意义。

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

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

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

编辑扩大多台服务器:

好的问题。

采取的步骤:

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

  2. 调用shell:现在你有问题来调用shell。一般你不想。为什么不?因为shell(任务)可能会运行很长时间。所以这就是我们之间使用队列的原因。所以你可以询问队列或让队列消息告诉你已经完成了一些事情。例如,想想一个关闭的邮件服务器。您必须重试等。这不应该在Web请求中,因为用户正在等待响应。

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

无论如何,有一些选项可以直接从控制器进行调用,但不应该这样做。这篇文章给出了一些非常有趣的见解: CakePHP: Run shell job from controller

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

+0

我还需要手动调用此操作(例如,通过单击视图中的按钮)。你是否建议我创建一个任务而不是控制器动作,并调用它(自动使用cron作业并手动点击)?是一个你称之为完全与逻辑分离的shell还是你在谈论队列?有时我需要一次发送多封电子邮件(当它自动检查时),但不应该太频繁发生,所以我想知道队列是否有点太复杂,无法满足我的需求!感谢您的回答 – Catherine

+0

也回答了他们,一般来说,您应该考虑应用的大小和设计。我回答你的问题的方式是它应该完成的方式之一。这并不意味着这是对商业有利的方式。如果您只是发送邮件,则不值得为它创建一个完整且更复杂的设置。 –

+1

再次感谢您的详细解答。我们同意不需要手动发送电子邮件,所以我创建了一个发送电子邮件的shell。这也迫使我将更多的方法从控制器转移到模型上,如果我理解得好,模型更合适。然后我按照这个过程设置了cron作业:http://book.cakephp.org/2.0/en/console-and-shells/cron-jobs.html我决定不使用队列,即使这看起来很有趣,因为它在这种情况下不值得! – Catherine

0

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

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

+0

我已经试过只是为了忘记地址,它似乎没有按照我想要的方式执行操作,我可能做错了。尽管我还没有尝试将它放在crontab中,但我猜测我应该在未来做更多的尝试。谢谢对不起,我不能评价你,我还是新来的网站。 – Catherine