Как настроить cron для работы скрипта, который является частью Zend Framework проекта - PullRequest
9 голосов
/ 19 ноября 2011

У меня есть проект Zendframework, для которого мне нужно периодически запускать сценарий для загрузки содержимого папки, а другой загружать. Сам сценарий готов, но я изо всех сил пытаюсь выяснить, где и как настроить скрипт для запуска. Я пробовал рысь и кудри до сих пор. Сначала у меня была ошибка, связанная с ошибкой в ​​указанном контроллере, и я это исправил, но теперь при запуске сценария у меня просто появляется пустой экран, но файлы не загружаются.

Для проекта zendframework, как мне настроить скрипт для запуска cron?

EDIT: Моя структура проекта выглядит так:

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 ]

10 голосов
/ 03 декабря 2011

Спасибо всем за ваши ответы. Однако решение, которое работало для меня, пришло с этого сайта Howto: Zend Framework Cron . Исходная ссылка не работает, но ее копию можно найти в интернет-архиве.

Я публикую здесь фрагмент кода. Но, пожалуйста, это не мое решение. Все кредиты переходит к первоначальному автору.

Хитрость с cronjobs в том, что вы не хотите загружать весь View часть ZF, нам не нужен какой-либо вывод HTML! Чтобы получить это работать, я определил новую константу в cronjob.php, который я проверю для в 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();
}
2 голосов
/ 19 ноября 2011

Во-первых, убедитесь, что у вас есть это в верхней части вашего скрипта PHP (за которым следует открывающий тег PHP):

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

Во-вторых, убедитесь, что права доступа правильные. Например, если вы создаете задание cron под root, то я считаю, что 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 на что-то реальное и значимое . Подробнее об этом см. на этой странице (Google "Cron").


Отказ от ответственности : Я ни в коем случае не владелец cron. Пожалуйста, поправьте меня, если я ошибаюсь.

0 голосов
/ 19 ноября 2011

Я создал мини-приложение под названием 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 /в / Scripts / Index.php --b = folderScript для сценария сборки

Затем я перегружаю основной метод запуска загрузки Zend_application, как, например,

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 также использует хороший подход со своим приложением / консолью, возможно, стоит взглянуть на их настройку

...