Я хочу создать некоторую функцию для расписания сценариев php, например, если я хочу, чтобы tu запустил page.php 12/12/2012 12:12, я могу позвонить
schedule_script('12/12/2012 12:12','page.php');//or by passing a time/datetime object
или, например, вызывать один скрипт каждую минуту
schedule_interval(60,'page.php');//every 60s=1minute
я могу добавить еще одну функцию, чтобы увидеть, какой сценарий запланирован или удалить один из них.
Я хочу, чтобы эти функции работали как на платформах UNIX, так и на WINDOWS, я НЕ хочу уродливых решений, таких как выполнение скрипта на каждой странице сайта (я хочу запланировать эти команды, когда никто не находится на сайте) или с использованием реализаций «buisy wait» (используя sleep () в скрипте, который проверяет, есть ли запланированные задания) или что-то, что требует вмешательства пользователя (например, написать что-нибудь на консоли или открыть панель).
Я нашел команду «AT» на MSDOS (хорошо работает на всех окнах), но она очень простая, потому что она принимает только время, а не даты, в UNIX есть более мощная версия, но я не знаю, как ее использовать (и я хочу решение для обеих платформ).
Существует функция PHP, которая позволяет отложить выполнение сценария до определенного момента.
Итак, допустим, у меня есть cron.php
:
<?php // Usage: // cron.php [interval|schedule] [script] [interval|stamp] if(!isset($argc) || count($argc)!=2)die; // security precaution $time=(int)$argv[3]; // just in case :) if($argv[1]=='schedule'){ time_sleep_until((int)$_GET['until']); include_once($time); }elseif($argv[1]=='interval') while(true){ // this is actually an infinite loop (you didn't ask for an "until" date? can be arranged tho) usleep($time*1000); // earlier I said milliseconds: 1000msec is 1s, but this func is for microseconds: 1s = 1000000us include_once($argv[2]); } ?>
И ваш файл classes
/ functions
:
// Const form K2F - Are we on windows? define('ISWIN', strpos(strtolower(php_uname()),'win')!==false && strpos(strtolower(php_uname()),'darwin')===false ); // Function from K2F - runs a shell command without waiting (works on all OSes) function run($cmd){ ISWIN ? pclose(popen('start /B '.$cmd,'r')) : exec($cmd.' > /dev/null &'); } script_schedule($script,$time){ if(is_string($time))$time=strtotime($time); run('php -f -- schedule '.escapeshellarg($script).' '.$time); } script_interval($script,$mseconds){ run('php -f -- interval '.escapeshellarg($script).' '.$mseconds); }
Это должно сработать. Кстати, K2F – это эта структура, которая делает ваши мечты реальными. ;). Приветствия.
Изменить: если вы все еще хотите, чтобы части подсчитывали выполняемые задания и / или удаляли их (останавливая), я также могу помочь вам в этом. Просто ответь на мой пост, и мы продолжим.
$amt_time = "1"; $incr_time = "day"; $date = ""; $now= ''. date('Ym-d') .""; if (($amt_time!=='0') && ($incr_time!=='0')) { $date = strtotime(date("Ymd".strtotime($date))."+$amt_time $incr_time"); $startdate=''.date('Ym-d',$date) .""; } else { $startdate="0000-00-00"; } if ($now == $startdate) { include ('file.php'); }
Просто догадаться;) На самом деле, я мог бы иметь это в обратном порядке, но вы получите идею
Это моя реализация планировщика, мне нужно только запустить его, если он неактивен, и добавить все задания в таблицу заданий mysql (у меня уже есть один для моего основного скрипта), этот скрипт запустит все задания, готовые к исполнению ( таблица sql имеет поле datetime).
То, что я называю «Mutex», – это класс, который говорит, что работает одна или несколько копий скрипта и даже может отправлять команды запущенному сценарию через трубу (вам просто нужно создать новый мьютекс с тем же именем для всех скрипты), поэтому вы можете даже остановить запущенный скрипт из другого скрипта.
<?php //---logging--- $logfile = dirname(dirname(__FILE__)).'/scheduler.log'; $ob_file = fopen($logfile,'a'); function ob_file_callback($buffer) { global $ob_file; fwrite($ob_file,$buffer); } //--includes--- $inc=dirname(dirname(__FILE__)).'/.include/'; require_once($inc.'Mutex.php'); require_once($inc.'jobdb.php'); //--mutex--- //i call it mutex but it's nothing like POSIX mutex,it's a way to synchronyze scripts $m=new Mutex('jscheduler'); if(!$m->lock())//if this script is already running exit();//only one scheduler at time //---check loop--- set_time_limit(-1);//remove script time limit for(;;){ ob_start('ob_file_callback');//logging $j=jobdb_get_ready_jobs(true);//gets all ready jobs,works with mysql if($j!=null)//found some jobs foreach($j as $val){//run all jobs $ex='*SCRIPT NAME AND PARAMETERS HERE*'; if(!run_script($ex)) echo "UNABLE TO LAUNCH THE JOB!\n"; } $n=($j!=null)?count($j).'JOBS LAUNCHED':'NO JOBS'; sleep(60); if($m->has_to_stop())//yeah,i can stop this script from other scripts,it works with a file pipeline exit("# STOPPING SCHEDULER\n"); ob_end_flush();//LOGGING } ?>
Моя функция «run_script» работает так же, как функция «запуска» Sciberras.
Чтобы активировать планировщик, вы должны просто использовать эту команду
run_script('scheduler.php');
проверить, активен ли он
$m=new Mutex('jscheduler'); if(!$m->test_lock()) echo 'SCHEDULER IS ACTIVE'; else echo 'SCHEDULER IS INACTIVE';
и остановить планировщик
$m=new Mutex('jscheduler'); $m->ask_to_stop();//simply sent throught the pipe the command,now has_to_stop()will return true on the process that have gain the lock of the mutex echo 'STOPPING SCHEDULER...';
я, возможно, слишком далеко продвинулся в его реализации, во всяком случае может возникнуть проблема с «задержкой», например, если планировщик начинается с 0: 00.00, и у меня есть два сценария в 0: 01.01 и 0: 01.59 оба запускаются с 0 : 02,0. Чтобы исправить это «отставание», я могу вернуть все задания, запланированные в следующую минуту, и запланировать их, как в коде Sciberras, используя time_sleep_until. Это не создаст слишком много запущенных потоков (возможно, я захочу проверить, есть ли ограничение или падение производительности при запуске количества потоков HUDGE, но я уверен, что возникнут некоторые проблемы) и обеспечивает идеальное время, требующее только проверить, планировщик активен.