4 Stimmen

Planen von php-Skripten

Ich möchte einige Funktion erstellen, um php-Skripte zu planen, zum Beispiel, wenn ich tu run page.php am 12/12/2012 12:12 kann ich aufrufen

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

oder zum Beispiel jede Minute ein Skript aufrufen

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

Ich werde vielleicht eine andere Funktion hinzufügen, um zu sehen, welche Skripte geplant sind, oder eines davon löschen.

Ich möchte, dass diese Funktionen sowohl auf UNIX- als auch auf Windows-Plattformen funktionieren, ich möchte KEINE hässlichen Lösungen wie die Ausführung eines Skripts auf jeder Seite der Website (ich möchte diese Befehle planen, wenn niemand auf der Website ist) oder die Verwendung von "buisy wait"-Implementierungen (Verwendung von sleep() auf einem Skript, das prüft, ob es irgendwelche geplanten Jobs gibt) oder etwas, das Benutzereingriffe erfordert (wie etwas in die Konsole schreiben oder ein Panel öffnen).

Ich habe den "AT"-Befehl unter MSDOS gefunden (funktioniert unter allen Windows-Betriebssystemen), aber er ist sehr einfach, weil er nur die Zeit und nicht das Datum akzeptiert, es gibt eine leistungsfähigere Version unter UNIX, aber ich weiß nicht, wie man sie benutzt (und ich möchte eine Lösung für beide Plattformen).

3voto

Christian Punkte 26672

Es gibt eine PHP-Funktion, mit der Sie die Skriptausführung bis zu einem bestimmten Zeitpunkt verzögern können.

Nehmen wir also an, ich habe 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]);
       }

?>

Und Ihr classes / functions Datei:

// 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);
}

Es sollte funktionieren. Übrigens, K2F ist dieses Framework, das Ihre Träume schneller wahr werden lässt ;). Zum Wohl.

Edita: Wenn Sie noch die Teile über das Zählen laufender Aufträge und/oder das Löschen (Stoppen) von Aufträgen benötigen, kann ich Ihnen auch dabei helfen. Antworten Sie einfach auf meinen Beitrag, und wir werden uns weiter darum kümmern.

1voto

Plokko Punkte 545

Dies ist meine Implementierung des Schedulers, ich brauche nur, um es zu starten, wenn nicht aktiv ist und fügen Sie alle Jobs auf der Mysql-Job-Tabelle (ich habe bereits eine für mein Haupt-Skript), dieses Skript wird alle Jobs bereit, ausgeführt werden (die Sql-Tabelle haben ein Datetime-Feld) starten.

Was ich "Mutex" nenne, ist eine Klasse, die anzeigt, ob eine oder mehrere Kopien des Skripts laufen und sogar Befehle an das laufende Skript über eine Pipe senden kann (Sie müssen einfach eine neue Mutex mit dem gleichen Namen für alle Skripte erstellen), so dass Sie sogar ein laufendes Skript von einem anderen Skript aus anhalten können.

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

?>

Meine Funktion "run_script" funktioniert auf die gleiche Weise wie die Funktion "run" von Sciberras.

Um den Scheduler zu aktivieren, sollten Sie einfach diesen Befehl verwenden

 run_script('scheduler.php');

um zu prüfen, ob sie aktiv ist

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

und zum Anhalten des Schedulers

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

Vielleicht bin ich bei der Implementierung zu weit gegangen, auf jeden Fall kann es ein Problem der "Verzögerung" geben, z.B. wenn der Scheduler um 0:00.00 startet und ich zwei Skripte um 0:01.01 und 0:01.59 habe, werden beide um 0:02.0 gestartet. Um diese "Verzögerung" zu beheben, kann ich alle in der nächsten Minute geplanten Jobs zurückholen und sie wie im Sciberras-Code mit time_sleep_until planen. Dies wird nicht zu viele laufende Threads erzeugen (ich möchte vielleicht testen, ob es eine Grenze oder einen Leistungsabfall beim Starten einer HUDGE Menge von Threads gibt, aber ich bin mir sicher, dass es einige Probleme geben wird) und stellt ein perfektes Timing sicher, bei dem nur geprüft werden muss, ob der Scheduler aktiv ist.

0voto

M2D 4YH Punkte 5
$amt_time = "1";
$incr_time = "day";
$date = "";
$now=  ''. date('Y-m-d') ."";   
if (($amt_time!=='0') && ($incr_time!=='0')) {
$date = strtotime(date("Y-m-d".strtotime($date))."+$amt_time $incr_time");
$startdate=''.date('Y-m-d',$date) ."";
} else {
$startdate="0000-00-00";
}
if ($now == $startdate) {
include ('file.php');
}

Nur eine Vermutung ;) Eigentlich könnte es auch umgekehrt sein, aber Sie haben die Idee

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X