Как запустить скрипты по Cron-у но без крона?

Если на хостинге нет CRON-а, а выполнять скрипты по расписанию нужно, можно пойти на “хитрости” (Вариант с переходом на другой хостинг/тариф/выделенный не рассматривается, поскольку слишком прост)

Прочитал у Never LEX-а (вообще, на блоге можно найти много интересного) статью про CRON для бедных - вспомнил, как сталкивался с аналогичной задачей. В общем-то, идея схожая - при открытии web-страницы проверяем время последнего выполнения скрипта (используем специальный файл) и, при необходимости, запускаем скрипт.

От варианта, предложенного Lex-ом мой а-ля cron отличают всего лишь несколько моментов:

В файл-счетчик времени ничего не пишется. Индикатором последнего старта скрипта является время последнего изменения файла (файл открыл “w+” и сразу закрыл). Информацию о времени изменения файла получаем функцией filemtime.

В случае, если скрипт запускается “надолго”, непосредственный include приводит к увеличению времени выполнения скрипта для некоторых посетителей. Чтобы этого избежать, была реализована следующая схема:

Для “длительных” запусков использовался вариант с подгрузкой изображения через javascript :
document.write('<'+'img src="cronimg.php" alt="" />');

Скрипт cronimg.php отдает прозрачный gif-пиксель 1×1, умирает и… продолжает выполнение уже без соединения с браузером. Все дело в использовании register_shutdown_function (’cron_function’) - в параметре передаем имя нашей cron-функции, которая и будет выполнять требуемые действия.

Note:      Working directory of the script can change inside the shutdown function under some web servers, e.g. Apache.

Если в функции требуется работать с файлами, лучше использовать абсолютные пути (например, с использованием dirname(__FILE__)) - т.к. рабочий каталог внутри функции может измениться.

* Если сайт не особо посещаем, то, возможно выполнение скрипта с задержкой. Используя вместо конструкции javascript  -> img простой фрейм/iframe, мы добавим к “посетителям” поисковых роботов… (хоть некоторые роботы и обрабатывают картинки и даже из скриптов, текстовых пауков всё равно больше)… Однако, если и роботы не особо посещают Ваш сайт, то о “надежности” такого CRON-а можно забыть.

Некоторые из описанных конструкций можно использовать и в случае “стороннего” cron-а: сторонний сервер (примеры можно посмотреть на страничке у Never Lex-а) обращается к нужному файлу с нужной периодичностью, а обработка происходит уже у нас на хостинге.

При запуске длительных скриптов нельзя упускать из вида ограничения на время выполнения скрипта… Однако, и в этом случае можно “пойти на хитрости”.. Пожалуй, это тема для отдельной статьи.

10 PHP-функций, которые Вы, вероятно, никогда не используете:
http://infinity-infinity.com/2009/07/10-php-functions-you-probably-never-use/

Метки:

Автор будет признателен, если Вы поделитесь ссылкой на статью, которая Вам помогла:
BB-код (для вставки на форум)

html-код (для вставки в ЖЖ, WP, blogger и на страницы сайта)

ссылка (для отправки по почте)

Комментарии (2) к записи “Как запустить скрипты по Cron-у но без крона?”

  1. White сообщает :

    Альтернативный вариант - с отправкой пользователю

    Connection: close - говорит браузеру оборвать соединение при достижении конца файла
    Content-Length: n - устанавливает длину документа

    http://dron.by/post/kak-zakryt-soedinenie-i-prodolzhit-vypolnenie-skripta/

  2. мейкер сообщает :

    Спасибо, нашёл использование connection close как закрыть соединение и продолжить выполнение PHP скрипта

    <?php

    set_time_limit(0);
    ignore_user_abort(true);
    ob_start(); // start buffer
    // out page content
    echo “This make take some time, please wait”;
    $length = ob_get_length();
    // magic
    header(’Connection: close’);
    header(”Content-Length: ” . $length);
    header(”Content-Encoding: none”);
    header(”Accept-Ranges: bytes”);
    ob_end_flush();
    ob_flush();
    flush();
    // background
    echo “if you see this, i am not working =(”;
    //long, long operation
    for ($i = 0; $i <= 100000; $i++) {
    mail(”me@localhost”, “spam”, $i);
    }

Добавить комментарий