袁来如此的工作笔记
袁来如此的工作笔记
竹杖芒鞋轻胜马,谁怕? 一蓑烟雨任平生。

在虚拟主机上开发PHP定时任务

浏览量:172

what:
定时任务每执行过一次后会在同目录新建或替换两个文件,everdaytime.txt记录上次任务实际执行时间,logictime.txt记录上次任务本应该执行时间。将两个文件删除后就不会执行下次任务了,也就达到了终止的目的。

    举一反三:两个执行时间其实可以用GET参数传值,最后file_get_contents也可以换成include。

why:

how:
<?php
ignore_user_abort();//关掉浏览器后脚本继续执行
set_time_limit(0);//设置脚本执行时间无上限
ini_set(\memory_limit\,\512M\);//内存限制设置
$interval_time = 86400;//循环执行时间间隔
$url="http://".$_SERVER[\HTTP_HOST\].$_SERVER[\REQUEST_URI\];//获取本页面URL
$now = time();//现在的时间戳
$everdaytime = file_exists("everdaytime.txt")?file_get_contents("everdaytime.txt"):"";//上次任务执行实际时间
$logictime = file_exists("logictime.txt")?file_get_contents("logictime.txt"):"";//上次任务执行逻辑时间
if(!$everdaytime){//如果没有执行过循环任务
    _everday();//则立即执行一次
}else{
    $sleep = $now-strtotime($logictime);//计算出距上次逻辑执行时间已经过了多少秒
    if($sleep<$interval_time){//如果还没超过时间间隔
        sleep($interval_time-$sleep+rand(0,600));//则休眠对应时间(加上随机数延迟,防止误操作执行了多次导致并发)
        $logictime_now = file_exists("logictime.txt")?file_get_contents("logictime.txt"):"";//休眠后的逻辑时间
        if($logictime!=$logictime_now){exit;}//如果两个逻辑时间不相等,则说明休眠时间段内有程序执行过,本程序为多余程序,遂过滤掉
    }else{//如果已超过时间间隔
        while($sleep>=$interval_time){
            $sleep-=$interval_time;
            _everday($sleep);//则执行一次或多次
        }
    }
}

function _everday($interval=0){
    global $now;//获取当前时间戳
    $logic_date = $now-$interval;//逻辑时间戳=现在-时间差
    file_put_contents("everdaytime.txt",date("Y-m-d H:i:s",$now));//写入本次实际执行时间
    file_put_contents("logictime.txt",date("Y-m-d H:i:s",$logic_date));//写入本次逻辑执行时间
    //业务逻辑...
}
file_get_contents($url);//循环下一次执行本程序
exit;//删除本文件后程序将停止运行

打赏