使用Zend Framework创建cronjob

22

我正在尝试编写一个cronjob控制器,以便可以调用一个网站并执行所有模块的cronjob.php。现在我的问题是如何实现?

使用curl是否可行,这样我也可以计算出错误和成功的次数?

[更新]

我想我没有解释清楚。

我想做的是有一个文件,我可以像从http://server/cronjob中调用一样,并使其执行每个/application/modules/*/controller/CronjobController.php或者采用另一种方法,使得所有的cronjobs不是在同一个地方,而是在模块所在的相同位置。这将为我提供优势,如果一个模块不存在,它就不会尝试运行它的cronjob。

现在我的问题是,你会如何执行所有模块的CronjobController,或者你会采取完全不同的方式来保持其模块化?

我希望能够输出运行成功的cronjobs的数量和没有运行成功的cronjobs的数量。

13个回答

12
经过一些研究和很多拖延,我得出了一个简单的结论:一个ZF化的cron脚本应该包含所有你的Zend框架应用程序的功能 - 但不需要所有与视图相关的内容。 我通过在我的应用程序目录中创建一个新的cronjobfoo.php文件来实现此目标。 然后我从以下部分中取出最少的内容: -我的前端控制器(index.php) -我的bootstrap.php 我去掉了所有的视图内容,并专注于保持环境设置、数据库设置、自动加载器和注册表设置。 我花了一点时间来更正文档根变量并删除从我的启动引导复制的一些OO功能。
之后我只是编写代码……在我的情况下,它是编译并通过电子邮件发送每晚的报告。 使用Zend_Mail非常棒。 当我确信我的脚本按照我想要的方式工作时,我只需将其添加到我的crontab即可。
祝你好运!

10

我目前在使用Zend Framework,以下是代码示例。该脚本仅包括门户文件index.php,在此文件中引导了所有路径、环境和其他Zendy代码。通过在cron脚本中定义常量,我们取消了应用程序运行的最后一步。

这意味着应用程序只是设置而未引导。此时,我们开始引导所需的资源,就这样。

//public/index.php

if(!defined('DONT_RUN_APP') || DONT_RUN_APP == false) {  
    $application->bootstrap()->run();
}

// application/../cron/cronjob.php

define("DONT_RUN_APP",true);
require(realpath('/srv/www/project/public/index.php'));
$application->bootstrap('config');
$application->bootstrap('db');

//cron code follows

7
我建议不要将您的 cronjobs 放在公共访问的位置,因为它们可能会在正常时间之外被触发,并且根据其功能,可能会引起问题(我知道这不是您的意图,但将它们放入实际控制器中可以从浏览器访问)。例如,我有一个 cron 发送邮件。如果有人找到 cron URL 并开始频繁点击,那么我会一直收到垃圾邮件。

我的做法是创建一个 cron 文件夹,在其中创建一个 heartbeat.php,它为我引导 Zend Framework(减去 MVC)。它检查一个数据库,该数据库具有所有已安装的 cron 作业的列表,如果需要运行,则生成 cron 作业类的实例并运行它。

cron 作业只是一个抽象 cron 类的子类,该类具有诸如 install()、run()、deactivate() 等方法。

为了触发我的任务,我只需有一个简单的 crontab 条目,每 5 分钟运行一次,点击 heartbeat.php。到目前为止,在两个不同的站点上都非常有效。


我也考虑过滥用问题,但是我找到了一个简单的解决方案。通过只允许某些IP地址运行cronjob(在我的情况下只有127.0.0.1),我可以获得所需的安全性。全局cronjob类是一个有趣的想法 :) - Thomaschaaf

3

我也喜欢这个解决方案。请查看我的博客上更新的脚本版本:http://webdevbyjoss.blogspot.com/2010/09/running-zend-framework-application-from.html - webdevbyjoss

3

我有一个专用服务器的访问权限,最初为cron作业使用不同的引导程序。但是我最终厌恶了这个想法,希望能够在现有的MVC设置中完成此操作,而无需费心移动内容。

我创建了一个名为cron.sh的文件,将其保存在网站根目录下(而非公共目录),并在其中放置了一系列要运行的命令。由于我想一次运行多个命令,因此像往常一样在我的控制器中编写了PHP代码,并在cron.sh中添加了对这些URL的curl调用。例如:curl http://www.mysite.com/cron_controller/action。然后在cron界面上运行 bash /path/to/cron.sh

正如其他人指出的那样,你的cron作业可以被猜测到URL的任何人触发,所以总有这种提示。你可以通过许多不同的方式来找到解决方案。


1

1
为什么不创建一个 crontab.php 文件,包含或者引用 index.php 的引导文件呢?
考虑到引导文件执行了 Zend_Loader::registerAutoload(),你可以直接开始使用模块,例如:myModules_MyClass::doSomething(); 这样你就可以跳过控制器。控制器的工作是通过 http 控制访问。在这种情况下,你不需要控制器方法,因为你是本地访问。

0
我在Gregor的回答中添加了这篇文章。以下是结果:
//public/index.php 

// Run application, only if not started from command line (cli)
if (php_sapi_name() != 'cli' || !empty($_SERVER['REMOTE_ADDR'])) {
    $application->run();
}

谢谢 Gregor!


0
我的解决方案:
  • curl /cron
  • 全局计划任务方法将包含所有控制器
  • 检查每个控制器是否有 -> cron 方法
  • 如果有,运行它们。

公共计划任务 URL(用于 curl)不是问题,有许多方法可以避免滥用。如上所述,检查远程 IP 是最简单的方法。


0

在同一目录或cron作业文件夹中运行引导程序是没有意义的。我已经创建了一种更好、更容易实现cron作业工作的方法。请按照以下步骤使您的工作变得简单和智能:

  1. 创建一个cron作业文件夹,例如“cron”或“crobjob”等,任何您想要的名称。

  2. 有时我们需要在不同的时间间隔(如1小时间隔或1天间隔)内在服务器上运行cron作业。

  3. 在cron作业文件夹中创建一个文件,比如我创建了一个“init.php”,现在假设您想每天向用户发送一次通讯。您不需要在init.php中编写zend代码。

  4. 所以只需在init.php中设置curl函数,并将您的控制器操作的URL添加到该curl函数中。因为我们的主要目的是每天调用一个操作。例如,URL应该像这样:

https://www.example.com/cron/newsletters

因此,在curl函数中设置此URL,并在同一文件的init.php中调用此函数。

在上面的链接中,您可以看到“cron”是控制器,而“newsletters”是操作,您可以在其中执行您的工作,同样,不需要运行引导文件等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接