Pianificazione di script php

Voglio creare qualche function per programmare gli script php, per esempio se voglio tu eseguire page.php al 12/12/2012 12:12 posso call

schedule_script('12/12/2012 12:12','page.php');//or by passing a time/datetime object 

o per esempio chiama uno script each minuto

 schedule_interval(60,'page.php');//every 60s=1minute 

potrei aggiungere qualche altra function per vedere quale script è programmato o cancellarne uno.

Voglio che queste funzioni funzionino su entrambe le piattaforms UNIX e WINDOWS, NON voglio soluzioni brutte come l'esecuzione di uno script su each pagina del sito (voglio programmare questi comandi quando nessuno è sul sito) o utilizzando le implementazioni "buisy wait" (usando sleep () su uno script che controlla se ci sono lavori programmati) o qualcosa che richiede l'intervento dell'utente (come scrivere qualcosa in console o aprire un pannello).

Ho trovato il command "AT" su MSDOS (funziona bene su tutte le windows) ma è molto semplice perché accetta solo il tempo e non le date, c'è una versione più potente su UNIX ma non so come usarla (e voglio una soluzione per entrambe le piattaforms).

C'è una function PHP che ti permette di ritardare l'esecuzione dello script fino ad un certo punto nel tempo.

Quindi diciamo che ho 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]); } ?> 

E il tuo file di classs / 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); } 

Dovrebbe funzionare. A proposito, K2F è la struttura che fa avverare i tuoi seach … più veloce. ;). Saluti.

Modifica: se desideri ancora che le parti contino i lavori in esecuzione e / o eliminati (fermandoli), posso aiutarti anche con esso. Rispondi al mio post e noi seguiremo.

 $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'); } 

Solo una supposizione;) In realtà potrei averlo in senso inverso ma tu hai l'idea

Questa è la mia implementazione dello scheduler, devo solo lanciarla se non è triggers e aggiungere tutti i lavori sulla tabella dei lavori mysql (ne ho già uno per il mio script principale), questo script avvierà tutti i lavori pronti per essere eseguiti ( la tabella sql ha un field datetime).

Quello che io chiamo "Mutex" è una class che dice se una o più copie dello script è in esecuzione e può persino submit comandi allo script in esecuzione attraverso una pipe (devi semplicemente creare un nuovo mutex con lo stesso nome per tutti gli script) in modo da poter persino interrompere uno script in esecuzione da un altro script.

 <?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 } ?> 

La mia function "run_script" funziona allo stesso modo della function "run" di Sciberras.

Per triggersre lo scheduler dovresti semplicemente usare questo command

  run_script('scheduler.php'); 

per verificare se è attivo

 $m=new Mutex('jscheduler'); if(!$m->test_lock()) echo 'SCHEDULER IS ACTIVE'; else echo 'SCHEDULER IS INACTIVE'; 

e per fermare lo scheduler

 $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...'; 

Potrei essere andato troppo lontano nella sua implementazione, comunque potrebbe esserci un problema di "lag", ad esempio se lo scheduler inizia alle 0: 00.00 e ho due script a 0: 01.01 e 0: 01.59 entrambi sono lanciati a 0 : 02.0. Per risolvere questo "ritardo" potrò recuperare tutti i lavori pianificati nel minuto successivo e programmarli come nel codice Sciberras utilizzando time_sleep_until. Questo non creerà troppi thread in esecuzione (potrei voler verificare se c'è un limite o una riduzione delle performance all'avvio di una quantità di thread di HUDGE ma sono sicuro che ci saranno dei problemi) e assicurerà un timing perfetto che richiede solo di verificare se il lo scheduler è attivo.