Главная · Статьи · Файлы · Фото галерея · Видео онлайн
Библиотека
По авторам
По жанрам
Поиск по названию
Навигация
Главная
Статьи
Файлы
Обратная связь
Фото галерея
Видео онлайн
Поиск

Работа
Заказать сайт или программу

Примеры работ
Последние статьи
Технология уничтожения
«Мы – русские»
Ф.М. Достоевский - Д...
Европа против России...
Первые английские ко...
Reklama

Фоновое выполнение скрипта на PHP без crontab
Озадачили меня тут написать демона на PHP. Т.е. скрипт, который будет заданное количество раз в заданное количество часов в случайное время (всегда случайное) выполнять определенные действия, и все это без использования cron'a.

До этого никогда не заморачивался, а тут после постановки задачи, начал было думать что так нельзя, что php скрипт надо вызывать браузером…ну задача то поставлена, надо выполнять.

Первая мысль — отключить ограничение времени выполнения скрипта. Запрещено хостером.

Вторая мысль — яваскриптом повторять аякс-запрос периодически (да хоть раз в секунду). — нельзя (требование заказчика).

Выяснилось, собственно, что и браузер открыт не должен быть, и крон нельзя использовать, и работать скрипт должен независимо от пользователя, бесконечно долго. Естественно, он должен минимум грузить систему.

1. Пачка сигарет, ночь, гугл, доки, книги, мануалы….
goto 1…

На выходе получаю:
Задача_1:
Реализовать генератор времен выполнения скрипта, исходя из заданных количества раз и количества часов. Хранить где-то эти времена.

Задача_2:
Работать после закрытия браузера

Задача_3:
Не вылетать после окончания ограничения времени выполнения скрипта

Задача_4:
Выполнять в нужное время какие-то действия.

Итак…
Пишем в конфиге исходные данные:

session_start();  // Старт сессии
$num_starts = 120; // Количество запусков скрипта за промежуток времени
$hours = 1; // Количество часов, в течение которых нужно запускать скрипт $num_starts раз.
$time_sec = $hours*3600; // Количество секунд в цикле запусков
$time_to_start = array(); // Собственно, массив с временами запусков
ignore_user_abort(1);   // Игнорировать обрыв связи с браузером 


Далее пишем функцию, которая поможет нам сгенерировать времена запуска.
В ней мы генерируем случайное число от 0 до количества секунд в исходном интервале.
/******
* @desc  Генерируем интервал между запусками.
*/
function add_time2start() {
    global $time_sec, $time_to_start;
    $new_time = time()+rand(0, $time_sec);
    if (!in_array($new_time, $time_to_start)) {   // Если такого времени в массиве нет - добавим
        $time_to_start[] = $new_time;
    } else {
        add_time2start(); // Если такое время уже есть - генерируем заново.
    }
}


Далее сгенерируем и запишем в сессию массив времен запуска. Предварительно отсортируем массив по возрастанию, чтобы сначала шло раннее время (машину времени я еще не успел создать).

$k = 1;
if ($_SESSION["num_st"] == "" || $_SESSION["num_st"][$num_starts-1] < time()) {   // проверка, что в сессию не записаны данные и что эти данные не устарели.
    do {
        add_time2start($k);                                        
        $k++;
    } while ($k < = $num_starts);
    sort($time_to_start, SORT_NUMERIC);       
    $_SESSION["num_st"] = $time_to_start;
}


Теперь надо заставить скрипт работать, не обращая внимания на максимальное время выполнения, установленное сервером.
Принцип таков:
1) Определяем время начала работы скрипта;
2) Определяем установленное ограничение на время выполнения.
3) Запускаем цикл, внутри которого считаем текущее время и вычисляем общее время работы скрипта, сверяем текущее время со значениями в массиве времен запуска, и если совпадение есть, выполняем заданные действия (у меня они в файле exec.php). Для запуска файлов используем сокеты.
4) Повторяем цикл пока время работы скрипта не приблизится к максимально разрешенному. Я поставил — пока до максимального времени не останется 5 секунд.

Итак… считаем начальные данные по времени:

$start_time = microtime(); // Узнаем время запуска скрипта   
$start_array = explode(" ",$start_time); // Разделяем секунды и миллисекунды
$start_time = $start_array[1]; // получаем стартовое время скрипта
$max_exec = ini_get("max_execution_time"); //Получаем максимально возможное время работы скрипта

Собственно, цикл. Комментарии в коде.

do{
    $nowtime = time();  // Текущее время
    //// Если текущее время есть в массиве с временами выполнения скрипта......
    if (in_array($nowtime, $_SESSION["num_st"])) {
        // Сокетом цепляемся к файлу с основным содержанием действий
        $http = fsockopen('test.ru',80);
        /// заодно передаем ему данные сессии и время когда он должен сработать
        fputs($http, "GET http://test.ru/exec.php?".session_name()."=".session_id()."&nowtime=$nowtime HTTP/1.0\r\n"); 
        fputs($http, "Host: test.ru\r\n");
        fputs($http, "\r\n");
        fclose($http);
    } //// выполнили заданное действие
    // Узнаем текущее время чтобы проверить, дальше ли вести цикл или перезапустить
        $now_time = microtime();
        $now_array = explode(" ",$now_time);
        $now_time = $now_array[1];
        // вычитаем из текущего времени начальное начальное
        $exec_time = $now_time - $start_time+$exec_time;
        /// тормозимся на секунду
        usleep(1000000);
        //Остановка скрипта, работающего в фоновом режиме. Я другого способа не придумал.
        if (file_exists("stop.txt")) exit;
        //Проверяем время работы, если до конца работы скрипта
        //осталось менее 5 секунд, завершаем работу цикла. 
} while($exec_time < ($max_exec - 5));


Ну и, если разрешенное время подходит к концу, то завершаем цикл и благополучно запускаем этот же скрипт другие процессом (в 5 секунд точно уложимся)

// Запускаем этот же скрипт новым процессом и завершаем работу текущего
$http = fsockopen('test.ru',80);
fputs($http, "GET http://test.ru/index.php?".session_name()."=".session_id()."&bu=$max_exec HTTP/1.0\r\n");
fputs($http, "Host: test.ru\r\n");
fputs($http, "\r\n");
fclose($http); 


Собственно, готово.
Далее у меня много заморочек было в выполнении тех самых действий — там надо было робота написать для поиска ссылок по заданным ссылкам.

Когда дописал все, озадачился полезным применением…Использовать его можно как службу. Он может следить за чем-то в сети и уведомлять Вас, например, по почте. И не надо никаких cron'ов.

Скрипт можно еще оптимизировать — доработкой не занимался.
Кстати, вот от чего я не смог оторваться — браузер все же придется открыть, чтобы изначально запустить скрипт.
Комментарии
Нет комментариев.
Добавить комментарий
Пожалуйста залогиньтесь для добавления комментария.
Рейтинги
Рейтинг доступен только для пользователей.

Пожалуйста, залогиньтесь или зарегистрируйтесь для голосования.

Нет данных для оценки.
Гость
Имя

Пароль



Забыли пароль?
Запросите новый здесь.
Сейчас на сайте
Гостей: 1
На сайте нет зарегистрированных пользователей

Пользователей: 1
Не активированный пользователь: 0
новичок: AMD
Статистика
Яндекс.Метрика
Rambler's Top100


PR-CY.ru
Protected by Copyscape Online Plagiarism Checker
Back To Top Back To Top Back To Top

Best Viewed 1280x1024