如何设置作为zend框架项目一部分的脚本的cron作业

时间:2011-11-19 01:03:44

标签: zend-framework cron

我有一个zendframework项目,我需要定期运行脚本来上传文件夹的内容,另一个需要下载。脚本本身已准备好但我正在努力弄清楚在哪里或如何设置要运行的脚本。到目前为止,我尝试过ly and和卷曲。我首先得到一个关于指定控制器错误的错误,我修复了但现在我只是在运行脚本时得到一个空白的屏幕,但文件没有上传。

对于zendframework项目,如何设置由cron运行的脚本?

修改 我的项目结构如下所示:

mydomain.com

    application
    library
    logs
    public
        index.php
    scripts
        cronjob.php
    tests

cronjob.php是我需要运行的脚本。其中前几行是:

<?php
define("_CRONJOB_",true);
require('/var/www/remotedomain.info/public/index.php');

我还修改了我的index.php文件,如下所示:

// Create application, bootstrap, and run
$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();

/** Cronjobs don't need all the extra's **/
if(!defined('_CRONJOB_') || _CRONJOB_ == false)
{
    $application->bootstrap()->run();
}

但是现在我现在尝试运行脚本时,收到消息:

Message: Invalid controller specified (scripts).

这是否意味着我需要为此目的创建一个控制器?但脚本文件夹位于应用程序文件夹之外。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:10)

感谢大家的回答。但是,适用于我的解决方案来自此网站Howto: Zend Framework Cron。原始链接已失效,但可以在Internet Archive上找到its copy

我在这里发布了一些代码。但请这不是我的解决方案。所有学分都归原作者所有。

  

cronjobs的诀窍是你不想加载整个View   ZF的一部分,我们不需要任何类型的HTML输出!要做到这一点   工作,我在cronjob.php中定义了一个新的常量,我将检查   for index.php。

cronjob.php

define("_CRONJOB_",true);
require('/var/www/vhosts/domain.com/public/index.php');
// rest of your code goes here, you can use all Zend components now!

的index.php

date_default_timezone_set('Europe/Amsterdam');

// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
|| define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));

/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
APPLICATION_ENV,
APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap();

/** Cronjobs don't need all the extra's **/
if(!defined('_CRONJOB_') || _CRONJOB_ == false)
{
$application->bootstrap()->run();
}

答案 1 :(得分:2)

首先,确保在PHP脚本的顶部(后面是打开的PHP标记)中包含此内容:

#!/usr/bin/php
<?php
    // ...

其次,确保权限正确。例如,如果您在root下创建cron作业,那么我相信如果我没有弄错的话,root会尝试运行PHP脚本。同样,如果您在其他用户下创建cron作业,他们最好拥有PHP脚本的正确权限。

例如(注意,根据您的服务器环境,需要相应地调整权限。例如,这只是一个假设的例子)

$ chmod 755 script.php
$ chown userThatRunsScriptWithCron script.php

如果您想要查看当前用户的当前cron作业,请执行以下操作:

$ crontab -l

或者,如果您的cron作业是在cron.hourly,cron.weekly等文件夹中设置的,那么您可以通过以下方式查看哪些用户“拥有”这些作业:

$ cat /etc/crontab

然后在文件的底部你会看到它们。

现在,要设置cron作业,请运行此命令以打开编辑器:

$ crontab -e

然后输入您的值:

1 2 3 4 5 php /path/to/script.php

现在保存并关闭文件。显然,您要将1 2 3 4 5更改为 real 有意义的。有关详细信息,请参阅this page(google“cron”)。


免责声明:无论如何,我不是cron master。如果我错了,请纠正我。

答案 2 :(得分:0)

我所做的是创建一个名为Scripts的迷你应用程序,其结构为:

Scripts
 -- Jobs
 -- Builds
 Abstract.php //abstract each job / build inherit from
 Bootstrap.php
 Index.php

然后我使用php /path/to/Scripts/Index.php --j = folderScript或/path/to/Scripts/Index.php --b = folderScript构建脚本

然后我重载主要的zend_application bootstrap run方法,如此

public function run()
{
    $opts = new Zend_Console_Getopt(array(
                'build|b-s' => 'Cron Build Script to Run',
                'job|j-s' => 'Cron Job to run',
                'params|p-s' => 'Parameters to set',
            ));

    $opts->parse();

    $front = $this->getResource('FrontController');

    if (true === isset($opts->params)) {
        parse_str($opts->params, $params);
        $front->setParams($params);
    }

    $filter = new Zend_Filter_Word_CamelCaseToUnderscore();

    if (true === isset($opts->build)) {
        $build = $filter->filter($opts->build);
        $className = sprintf('Scripts_Build_%s', ucfirst($build));
    } else if (true === isset($opts->job)) {
        $job = $filter->filter($opts->job);
        $className = sprintf('Scripts_Jobs_%s', ucfirst($job));
    } else {
        $className = 'Scripts_Jobs_Dynamic';
    }

    if (false === class_exists($className)) {
        throw new Exception('Class "' . $className . '" Does Not Exist');
    } else {
        $front->setParam('bootstrap', $this);

        $logger = $this->initLogger();

        $fp = fopen(DATA_PATH . '/locks/' . md5($className), 'w+');

        if (!flock($fp, LOCK_EX | LOCK_NB)) {
            $logger->info('Already Running');
            exit(0);
        }

        $logger->Subject($className);

        fwrite($fp, time());

        try {
            $class = new $className();

            $class->setLogger($logger)
                    ->init()
                    ->run();

            $logger->done('Operation Completed');
        } catch (Exception $e) {
            $logger->err($e->getMessage() . ' ' . $e->getTraceAsString());
            $logger->done('done with error');
        }

        flock($fp, LOCK_UN);
    }
}

希望能让你开始,我看着在ZF中使用控制器/模块,但看起来似乎太多了开销

Symfony也使用他们的应用/控制台的好方法,值得研究他们的设置