TP5执行定时计划任务可在程序中配置

假设网站根目录为:/data/www/tp5/,配置文件目录为:/data/www/tp5/conf,每个模块的所在的目录为:/data/www/tp5/app

第一步:修改功能配置文件新增以下配置(/data/www/tp5/conf/config.php)

/*每分钟*/
/*每n分钟*/
/*每小时 某分*/
/*每天 某时:某分*/
/*每周-某天 某时:某分  0=周日*/
/*每月-某天 某时:某分*/
/*某月-某日 某时-某分*/
/*某年-某月-某日 某时-某分*/
'sys_crond_timer' => array('*', '*/', '*:i', 'H:i', '@-w H:i', '*-d H:i', 'm-d H:i', 'Y-m-d H:i'),

第二步:新增计划任务配置文件(/data/www/tp5/conf/extra/crond.php):

?php
/**
 * Created by PhpStorm.
 * Date: 2018/11/12
 * Time: 16:53
 * User: xuejie
 * Email: 513569228@qq.com
 * URL: http://www.xuejiehome.com
 * 计划任务的配置表
 */
      
$crond_list = array(
    '*/' => [
        [
            'minutes' => 3,//每3分钟
            'methods' => [
                [
                    'method' => '\app\send\crontab\SendPrizeCallback',
                    'params' => []
                ],
                [
                    'method' => '\app\lottery2\crontab\SendPrize',
                    'params' => []
                ],
            ]
        ],
        [
            'minutes' => 5,//每5分钟
            'methods' => [
                [
                    'method' => '\app\send\crontab\SendPrize',
                    'params' => []
                ],
            ]
        ],
        [
            'minutes' => 10,//每10分钟
            'methods' => [
                [
                    'method' => '\app\send\crontab\ProcessTimeoutQueue',
                    'params' => []
                ],
                [
                    'method' => '\app\lottery2\crontab\ProcessTimeoutQueue',
                    'params' => []
                ],
            ]
        ]
      
    ],  //每n分钟
    '00:00' => [
//        [
//            'method' => '\app\lottery2\crontab\ReturnPrizeStock',
//            'params' => [
//                'activity_mark' => 'CH201800035',
//            ]
//        ],
    ],  //每天 ------------
    '*-01 00:00' => [
      
    ],  //每月--------
    '*:00' => [
    ],  //每小时---------
      
);
      
return $crond_list;

第三步:编写第二步中具体要执行的任务文件,以下实例中为使用某些方法继承Command,可根据实际情况决定是否需要。

(1)如第二步配置中注释掉的需要传递参数的ReturnPrizeStock文件(/data/www/tp5/app/lottery2/crontab/ReturnPrizeStock.php)

<?php
      
namespace app\lottery2\crontab;
      
use think\Config;
use think\console\Command;
use think\console\Output;
use think\Request;
      
class ReturnPrizeStock extends Command
{
    protected function configure()
    {
        $this->setName('app:lottery2-return-prize-stock')
            ->setDescription('Increase the stock of the prize that the win is expired.')
            ->setHelp('Increase the stock of the prize that the win is expired.');
    }
      
    public function doRun($post = array())
    {
        $request = Request::instance();
        $request->post($post);
      
        Config::load(CONF_PATH . 'lottery2/config.php');
        $request->module("lottery2");
      
        $output = new Output();
        $output->writeln(controller('lottery2/Prize')->returnStock());
    }
}

(2)如第二步配置中的ProcessTimeoutQueue任务(/data/www/tp5/app/send/crontab/ProcessTimeoutQueue.php)

<?php
      
namespace app\send\crontab;
      
use think\Config;
use think\console\Command;
use think\console\Output;
use think\Request;
      
class ProcessTimeoutQueue extends Command
{
    protected function configure()
    {
        $this->setName('crontab:send-process-timeout-queue')
            ->setDescription('Update process_status of the queue from 2 to 0.')
            ->setHelp('Update process_status of the queue from 2 to 0.');
    }
      
    public function doRun($post = array())
    {
        if (empty($post)) {
            $post['from_process_status'] = 2;
            $post['to_process_status'] = 0;
            $post['space_update_time'] = 100;
        }
      
        //设置post数据
        $request = Request::instance();
        $request->post($post);
      
        Config::load(CONF_PATH . 'send/config.php');
        $request->module("send");
      
        $output = new Output();
        $output->writeln(controller('send/Queue')->updateProcessStatus());
    }
}

第四步:编写计划任务的执行文件,将其写在公共目录下,创建自定义命令"php think app:crond",(/data/www/tp5/app/common/library/Crond.php)

<?php
/**
 * Created by PhpStorm.
 * Date: 2018/11/12
 * Time: 16:27
 * User: xuejie
 * Email: 513569228@qq.com
 * URL: http://www.xuejiehome.com
 */
      
namespace app\common\library;
      
use think\Config;
use think\console\Command;
use think\console\Input;
use think\console\Output;
      
class Crond extends Command
{
    protected function configure()
    {
        $this->setName('app:crond')
            ->setDescription('crontab 计划任务');
    }
      
    protected function execute(Input $input, Output $output)
    {
        $this->doCron();
    }
      
    public function doCron()
    {
        // 记录开始运行的时间
        $GLOBALS['_beginTime'] = microtime(TRUE);
      
        /* 永不超时 */
        ini_set('max_execution_time', 0);
        $time = time();
        $exe_method = [];
        $crond_list = Config::get('crond');   //获取第二步的文件配置,根据自己版本调整一下
        $sys_crond_timer = Config::get('sys_crond_timer');
        foreach ($sys_crond_timer as $format) {
            if ($format == '*/') {
                //每n分钟单独处理
                if (isset($crond_list[$format])) {
                    $minute = date('i', $time);
                    foreach ($crond_list[$format] as $v) {
                        if (isset($v['minutes']) && $minute % $v['minutes'] == 0 && isset($v['methods'])) {
                            $exe_method = array_merge($exe_method, $v['methods']);
                        }
                    }
                }
            } else {
                $key = date($format, ceil($time));
      
                if (isset($crond_list[$key]) && is_array(@$crond_list[$key])) {
                    $exe_method = array_merge($exe_method, $crond_list[$key]);
                }
            }
        }
      
        if (!empty($exe_method)) {
            foreach ($exe_method as $method) {
                if (!isset($method['method'])) {
                    continue;
                }
                echo date('Y-m-d H:i:s') . " --- crond --- {$method['method']}\n";
                $runtime_start = microtime(true);
      
                $methodInstance = new $method['method']();
                $methodPostData = isset($method['params']) ? $method['params'] : array();
                $methodInstance->doRun($methodPostData);
      
                $runtime = microtime(true) - $runtime_start;
      
                echo "{$method['method']}, cost time: {$runtime}\n\n";
            }
      
            $time_total = microtime(true) - $GLOBALS['_beginTime'];
            echo "total:{$time_total}\n";
        }
    }
}


第五步:修改公共的命令行配置文件增加任务命令(/data/www/tp5/conf/command.php)

<?php
return [
    \app\common\library\Crond::class,//计划任务
];

第六步:添加计划任务,每分钟执行一次,调用第四步中的自定义命令,检测并执行第二步中配置的需要执行的任务。

*/1 * * * * /usr/bin/php/data/www/tp5/think app:crond >> /data/logs/tp5/crontab.log 2>&1

注:

本文使用到TP5的自定义命令行功能,由于该文配置文件目录已不是默认配置目录,如有疑问可参考文章:TP5自定义命令行

by 雪洁 2019-04-17 10:19:09 2133 views

1 Comments

zsheng 2019-12-12 13:29:56
第六步应该写在哪?
雪洁 2019-12-12 13:31:11
Linux的话命令是crontab -e ,windows的可百度搜索添加定时任务的方法。
我来说几句

相关文章