2011-01-03 9 views
14

Ich muss ein Task-System, das in der Lage sein sollte, auf Servern arbeiten, die Crontab nicht unterstützt.PHP-Funktion, die eine Cron-Zeichenfolge erhalten und die nächste Laufzeit Timestamp

Ich frage, ob es einen bestehenden Code, der einen cron-String nehmen (zB ‚0 0,12 1 */2 *‘ und den Zeitstempel der nächsten geplanten Lauf zurück.

Wenn eine solche Code könnte dann nicht gefunden werden, wie soll ich damit anfangen

+0

http://stackoverflow.com/questions/321494/calculate-when-a-cron-job-will-be-executed-then-next-time/3453872#3453872 –

Antwort

12

Sie diese Klasse verwenden könnte PHP-Parse-cron-strings-and-compute-schedules

Es wird auch den letzten geplanten Lauf

+3

siehe auch http: // stackoverflow.com/questions/321494/calculate-wann-ein-cron-job-wird-ausgeführt-dann-nächste-zeit – berebidahoo

+0

Ich benutze die PHP-Parse cron-Klasse, um Sub-Crons auf zwei Servern zu laufen, und ich hatte keine einzelnes Problem damit – Patrick

8

mit dieser Funktion berechnen:

function parse_crontab($time, $crontab) 
     {$time=explode(' ', date('i G j n w', strtotime($time))); 
      $crontab=explode(' ', $crontab); 
      foreach ($crontab as $k=>&$v) 
        {$time[$k]=intval($time[$k]); 
        $v=explode(',', $v); 
        foreach ($v as &$v1) 
          {$v1=preg_replace(array('/^\*$/', '/^\d+$/', '/^(\d+)\-(\d+)$/', '/^\*\/(\d+)$/'), 
              array('true', $time[$k].'===\0', '(\1<='.$time[$k].' and '.$time[$k].'<=\2)', $time[$k].'%\1===0'), 
              $v1 
              ); 
          } 
        $v='('.implode(' or ', $v).')'; 
        } 
      $crontab=implode(' and ', $crontab); 
      return eval('return '.$crontab.';'); 
     } 
var_export(parse_crontab('2011-05-04 02:08:03', '*/2,3-5,9 2 3-5 */2 *')); 
var_export(parse_crontab('2011-05-04 02:08:03', '*/8 */2 */4 */5 *')); 
+0

Ehrfürchtige Funktion. Hier ist es mit einem Standard-Code-Stil. https://gist.github.com/goosehub/7deff7928be04ec99b4292be10b4b7b0 – Goose

+0

Ich habe einen Fehler in Ihrem Code gefunden. Sehen Sie meine Antwort für Erklärung und fühlen Sie sich frei, es auf Ihre Antwort anzuwenden. – Goose

+0

@Goose, denke ich, dass "$ time [$ k] = intval ($ time [$ k]);" ist in Ordnung. – diyism

0

In der parse_crontab Funktion:

ersetzen $time[$k] mit intval($time[$k]) in der preg_replace Linie
zwei vergleichen base10 Zahlen richtig.

+0

Können Sie bitte Ihre Antwort umformulieren? Es ist schwer zu verstehen. Ist eine parse_contab-Funktion verfügbar? Woher? Wie? Und was ist mit dem Ersetzen von Code? Schlägst du vor, die 'parse_contab'-Funktion anzupassen? – einpoklum

1

Ich fand, dass diyism eine große Antwort hatte, aber einen entscheidenden Fehler fand.

Wenn Sie eine Cron-Zeit wie 0 * * * * eingeben, wird sie bei 0 Minuten, 8, Minuten und 9 Minuten ausgeführt. Der Code gibt eine bedingte 08===0, die wahr zurückgibt, weil PHP Zahlen beginnend mit 0 als oktal interpretiert, und 08 und 09 sind keine gültigen Oktalzahlen, so dass sie als 0 interpretiert werden. Weitere Informationen finden Sie hier.

How to prevent PHP from doing octal math in conditionals? (why does 08 === 0)

Hier ist eine feste und gut Version von diyism Code kommentiert.

// Parse CRON frequency 
function parse_crontab($time, $crontab) { 
    // Get current minute, hour, day, month, weekday 
    $time = explode(' ', date('i G j n w', strtotime($time))); 
    // Split crontab by space 
    $crontab = explode(' ', $crontab); 
    // Foreach part of crontab 
    foreach ($crontab as $k => &$v) { 
     // Remove leading zeros to prevent octal comparison, but not if number is already 1 digit 
     $time[$k] = preg_replace('/^0+(?=\d)/', '', $time[$k]); 
     // 5,10,15 each treated as seperate parts 
     $v = explode(',', $v); 
     // Foreach part we now have 
     foreach ($v as &$v1) { 
      // Do preg_replace with regular expression to create evaluations from crontab 
      $v1 = preg_replace(
       // Regex 
       array(
        // * 
        '/^\*$/', 
        // 5 
        '/^\d+$/', 
        // 5-10 
        '/^(\d+)\-(\d+)$/', 
        // */5 
        '/^\*\/(\d+)$/' 
       ), 
       // Evaluations 
       // trim leading 0 to prevent octal comparison 
       array(
        // * is always true 
        'true', 
        // Check if it is currently that time, 
        $time[$k] . '===\0', 
        // Find if more than or equal lowest and lower or equal than highest 
        '(\1<=' . $time[$k] . ' and ' . $time[$k] . '<=\2)', 
        // Use modulus to find if true 
        $time[$k] . '%\1===0' 
       ), 
       // Subject we are working with 
       $v1 
      ); 
     } 
     // Join 5,10,15 with `or` conditional 
     $v = '(' . implode(' or ', $v) . ')'; 
    } 
    // Require each part is true with `and` conditional 
    $crontab = implode(' and ', $crontab); 
    // Evaluate total condition to find if true 
    return eval('return ' . $crontab . ';'); 
} 
+0

Ich denke, dass "$ time [$ k] = intval ($ time [$ k]);" ist in Ordnung, ich habe meine Antwort aktualisiert, danke. – diyism

+0

@diyism 'echo intval (09);' gibt 0, also müssen Sie leider $ time [$ k] = preg_replace ('/^0 + (? = \ D) /', '', $ verwenden Zeit [$ k]); ' – Goose

0

Ich schrieb eine sehr leistungsfähige PHP-Klasse namens CalendarEvent vor langer Zeit:

https://github.com/cubiclesoft/php-misc/

Es unterstützt zwei verschiedene Muster Syntaxen. Normales Cron kann bestimmte komplexe Muster nicht verarbeiten, während die standardmäßige CalendarEvent-Syntax jedes beliebige Zeitplanmuster behandelt, das Sie jemals benötigen könnten. Die Cron-Pattern-Syntax-Unterstützung ist eigentlich ein Fallback (Präfix Cron-Zeilen mit cron und ein Leerzeichen).

CalendarEvent wurde hauptsächlich als Kalenderereignis-Berechnungsklasse geschrieben und unterstützte zufällig die "nächsten Trigger" -Mechanismen im Cron-Stil. Es ist tatsächlich entworfen, um einen gesamten Zeitplan für mehrere Monate zu berechnen, um einen Kalender für einen Benutzer anzuzeigen (daher der Klassenname). Ich habe die Klasse auch als Zwischenlösung verwendet, um Ereignisse zwischen Kalenderplattformen zu übersetzen. Das ist das seltenere Szenario - ich habe es häufiger für AddSchedule()/NextTrigger() Cron-ähnliche Lösungen verwendet.