【码】PHP实现定时任务
in 代码片段 with 1 comment

【码】PHP实现定时任务

in 代码片段 with 1 comment

代码来源:自己整理编写
说明:核心在于sleep时间的计算和任务打标记

<?php
/**
 * PHP守护进程
 * @since   2016-06-01
 * @author  zhaoxiang <zhaoxiang051405@outlook.com>
 */

/**
 * 目前支持的时间配置有四种
 * 1、每天下午6时(18:00)  * 18 0
 * 2、每周一上午12时  1 12 0
 * 3、每个整点执行 * * 0
 * 4、每分钟执行一次 * * *
 *
 * 第一位表示周的第几天,0表示周日 1~6分别表示1~6
 * 第二位表示小时,只支持24小时制 0~23
 * 第三位表示分钟 0~59
 * 每位都以单个英文空格隔开
 */

declare(ticks = 1);

if (!isset($argc) || empty($argc)) {
    die ('allow run in console only.');
}

function update(){
    global $newConf;
    $newConf = [];
    $configFilePath = '';//your config file
    if( file_exists($configFilePath) ){
        $config = require($configFilePath);
        if( !is_array($config) || empty($config) ){
            die('Configuration file format is not correct');
        }
        foreach ( $config as $key => $value ){
            list($week, $hour, $minute) = explode(' ', $key);
            $week   = ($week == '*')  ?$week  :intval($week);
            $hour   = ($hour == '*')  ?$hour  :intval($hour);
            $minute = ($minute == '*')?$minute:intval($minute);
            if( $week === '*' ){
                for ( $i=0;$i<7;$i++ ){
                    if( $hour === '*' ){
                        for ( $k=0;$k<24;$k++ ){
                            if( $minute === '*' ){
                                for ( $j=0;$j<60;$j++ ){
                                    if( !isset($newConf[$i][$k][$j]) ){
                                        $newConf[$i][$k][$j] = [];
                                    }
                                    $newConf[$i][$k][$j] = array_merge($newConf[$i][$k][$j], $value);
                                }
                            }else{
                                if( !isset($newConf[$i][$k][$minute]) ){
                                    $newConf[$i][$k][$minute] = [];
                                }
                                $newConf[$i][$k][$minute] = array_merge($newConf[$i][$k][$minute], $value);
                            }
                        }
                    }else{
                        if( $minute === '*' ){
                            for ( $j=0;$j<60;$j++ ){
                                if( !isset($newConf[$i][$hour][$j]) ){
                                    $newConf[$i][$hour][$j] = [];
                                }
                                $newConf[$i][$hour][$j] = array_merge($newConf[$i][$hour][$j], $value);
                            }
                        }else{
                            if( !isset($newConf[$i][$hour][$minute]) ){
                                $newConf[$i][$hour][$minute] = [];
                            }
                            $newConf[$i][$hour][$minute] = array_merge($newConf[$i][$hour][$minute], $value);
                        }
                    }
                }
            }else{
                if( $hour === '*' ){
                    for ( $k=0;$k<24;$k++ ){
                        if( $minute === '*' ){
                            for ( $j=0;$j<60;$j++ ){
                                if( !isset($newConf[$week][$k][$j]) ){
                                    $newConf[$week][$k][$j] = [];
                                }
                                $newConf[$week][$k][$j] = array_merge($newConf[$week][$k][$j], $value);
                            }
                        }else{
                            if( !isset($newConf[$week][$k][$minute]) ){
                                $newConf[$week][$k][$minute] = [];
                            }
                            $newConf[$week][$k][$minute] = array_merge($newConf[$week][$k][$minute], $value);
                        }
                    }
                }else{
                    if( $minute === '*' ){
                        for ( $j=0;$j<60;$j++ ){
                            if( !isset($newConf[$week][$hour][$j]) ){
                                $newConf[$week][$hour][$j] = [];
                            }
                            $newConf[$week][$hour][$j] = array_merge($newConf[$week][$hour][$j], $value);
                        }
                    }else{
                        if( !isset($newConf[$week][$hour][$minute]) ){
                            $newConf[$week][$hour][$minute] = [];
                        }
                        $newConf[$week][$hour][$minute] = array_merge($newConf[$week][$hour][$minute], $value);
                    }
                }
            }
        }
    }else{
        die("Config file is not exists\n");
    }
}

update();

pcntl_signal(SIGUSR2, "update");

$longer = false;
$offset = 2; //为了容错增加2秒偏移

while (true){
    if( $longer ){
        $minute = $minute + 1;
    }else{
        $week = intval(date('w'));
        $hour = intval(date('G'));
        $minute = intval(date('i'));
        $hasDone = [];
    }
    $needDo = [];

    if( isset($newConf[$week]) ){
        if( isset($newConf[$week][$hour]) ){
            if( isset($newConf[$week][$hour][$minute]) ){
                $needDo = $newConf[$week][$hour][$minute];
            }else{
                for( $indexOffset=$minute;$indexOffset<60;$indexOffset++ ){
                    if( isset($newConf[$week][$hour][$indexOffset]) ){
                        $sleep = ($indexOffset - $minute) * 60 + $offset;
                        goto SKIP;
                    }
                }
                $sleep = (60 - $minute) * 60 + $offset;
                goto SKIP;
            }
        }else{
            $newHour = $hour + 1;
            $sleep = strtotime(date('Y-m-d')." {$newHour}:00") - time() + $offset;
            goto SKIP;
        }
    }else{
        $sleep = strtotime(date('Y-m-d', strtotime('+1 day'))." 00:00") - time() + $offset;
        goto SKIP;
    }

    if( !in_array($week.$hour.$minute, $hasDone) ){
        $start = time();
        //TODO::Something
        $end = time();
        $sleep = 60 - ($end - $start);
        if( $sleep < 0 ){
            $longer = true;
            $sleep = 0;
        }
        $hasDone[] = $week.$hour.$minute;
    }

    SKIP:
    sleep( $sleep );
}
Comments are closed.
  1. think you.