PHP定时任务

php

浏览数:97

2019-1-13


1定时任务 2检查重复启动 3可控开关 实现原理:睡眠一定时间,后再调用自身。优点:可控,避免重复启动,线程挂起节约计算机资源

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 *  定时任务
 */
class Task extends BASE_Controller {

    public function __construct() {
        parent::__construct();
        set_log('task_'.$this->router->fetch_method(),'线程被创建-----------');
        $this->load->driver('cache', array('adapter' => 'file', 'backup' => 'file'));
    }

    /**
     * 启动定时任务
     */
    private function run($interval_time=0){

        // 加载配置
        $this->config->load('task');
        $config = $this->config->item($this->router->fetch_method());
        if(!$config){
            $this->stop("请设置配置文件!");
        }

        // 间隔时间
        if($interval_time){
            $config['interval_time'] = $interval_time;
        }
        echo "下次任务被启动!";
        set_log('task_'.$this->router->fetch_method(),'下一次任务将在'.date("Y-m-d H:i:s", time()+$interval_time).'执行!');
        set_log('task_'.$this->router->fetch_method(),'本次线程完成'.PHP_EOL);

        // 线程挂起,间隔时间后再执行
        ignore_user_abort();//关掉浏览器,PHP脚本也可以继续执行.
        set_time_limit(0);// 不限时间
        sleep($config['interval_time']);// 每隔多长时间运行
        if($config['is_open']){
            // 回调请求
            $url = "http://".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
            file_get_contents($url);
        }else{
            $this->stop("该任务已被禁止启动,请到配置文件中开启!");
        }
    }

    /**
     * 停止任务
     */
    private function stop($tip){
        set_log('task_'.$this->router->fetch_method(),'线程被放弃!'.$tip.PHP_EOL);
        die($tip);
    }    /**
     * 计算收益【定时任务】
     */
    function calculate_profit(){

        // ---------1 校验任务 --------------

        $key = 'task_calculate_profit';
        $current_time = time();
        $day = date("Y-m-d",$current_time);
        $last_time = $this->cache->get($key);
        if ($last_time){

            // 如果当前时间等于上次执行的时间,说明今天任务已执行过,视为重复执行,则放弃
            if(date('Y-m-d',$current_time)==date('Y-m-d',$last_time)){
            //if($current_time - $last_time  < (5*60-10)){ // 测试
                $this->stop("该任务正在执行中,请勿重复开启!".($current_time - $last_time));
            }

        }

        // 算出下次间隔多长时间执行,即当前时间到明天某个时间点的时间差(主要实现指定时间点执行)
        $interval_time = strtotime('+1 day 01:00:00')-$current_time;
        //$interval_time = strtotime('+5 minute')-$current_time;// 测试
        $this->cache->save($key,$current_time, 5*60); // 记住本次执行时间,缓存一天        // ---------2 收益计算开始 --------------

        // 获取所有门店账户
        $this->load->model('admin_account_model','account_model');
        $this->load->model('admin_account_profit_model','account_profit_model');
        $account_list = $this->account_model->all();

        if($account_list){
            $list = $this->account_profit_model->jiesuan($account_list,$day);
        }

        $result = isset($list)&&$list?json_encode($list):"收益计算失败!";
        set_log($key,$result);

        // ---------3 启动下次任务 --------------
        $this->run($interval_time);

    }
}