thinkphp5.0定時任務

php定時任務

系統環境要求

  • linux環境
  • 裝有at命令
  • thinkphp5.0框架

開發人員必須會的

  1. 必須知道使用linux命令
  2. 必須瞭解at命令
  3. 必須知道thinkphp5.0框架的命令行開發
  4. 可以自己搭建php環境

在ThinkPHP5.0框架中の根目錄下存在如下文件

  1. think.php
  2. composer.json
  3. composer.lock

其中think.php就是我們需要使用到的文件。


具體實現

執行任務代碼實現

1、打開終端
2、使用cd命令進入到項目根目錄
3、進入到項目根目錄後,輸入命令行:

$ php think make:controller command/Task

4、然後可以看到application文件夾中多出了command文件夾,進入後可以看到Task.php文件

<?php
namespace app\Command;

use think\Controller;

class Task extends Controller
{
    //
}

5、接下來我們需要更改這個文件內容變爲如下:

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\input\Argument;
use think\console\Output;

class Task extends Command
{
    protected function configure()
    {
        $this->addArgument('test1',Argument::REQUIRED);  #必須參數
        $this->addArgument('test2',Argument::OPTIONAL);  #可選參數
        $this->setName('test')->setDescription('Command Test');
    }

    protected function execute(Input $input, Output $output)
    {
        $test1 = $input->getArgument('test1');
        $test2 = $input->getArgument('test2');
        #邏輯代碼
        //todo 

        #輸出代碼
        $output->writeln("TestCommand:test1=".json_encode($test1));
        $output->writeln("TestCommand:test2=".json_encode($test2));
    }
}

6、回到application目錄,找到command.php文件,增加新加入的類(包含命名空間)

return [
    'app\command\Task',
];

7、保存後,重新回到終端,輸入:

$ php think list
Think Console version 0.1

Usage:
  command [options] [arguments]

Options:
  -h, --help            Display this help message
  -V, --version         Display this console version
  -q, --quiet           Do not output any message
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Available commands:
  build              Build Application Dirs
  clear              Clear runtime file
  help               Displays help for a command
  list               Lists commands
  test               Command Test
  unit               phpunit
 make
  make:controller    Create a new resource controller class
  make:model         Create a new model class
 optimize
  optimize:autoload  Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.
  optimize:config    Build config and common file cache.
  optimize:route     Build route cache.
  optimize:schema    Build database schema cache.

8、可以看到Available commands:中有一個test命令,嘗試鍵入

$ php think test

  [RuntimeException]        #運行時異常
  Not enough arguments.     #缺少參數

9、提示異常信息!

$ php think test aaa bbb
TestCommand:test1="aaa"
TestCommand:test2="bbb"

10、運行結果與預期結果一致。至此,執行任務的代碼完成。


寫定時任務代碼實現

在application中創建工具類TimedTask

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/12/8 0008
 * Time: 上午 10:51
 * Administrator
 */

namespace app\util;

/**
 * Class TimedTask
 * @package app\util
 */
class TimedTask
{
    /**
     * 執行定時任務
     *
     * @param $command string think框架的command命令  例如:test
     * @param $time string 執行時間
     * 例如:①1-i表示一分鐘後執行   ②11am-time  上午11點
     * 如傳入具體時間 請使用格式 $time.'-time'
     * 如果是多少單位後執行 請使用  $num .'-*' 注:*代表 date方法中除秒之外的各時間格式  比如Y代表年
     * @param $argv string 執行參數  多個參數用空格隔離
     * @return string|array 執行結果
     */
    public static function timingExecution ($command,$time,$argv){
        list($num,$format) = explode('-',$time);
        switch ($format){
            case 'd':$execTime = 'now +'.$num.' days';break;
            case 'm':$execTime = 'now +'.$num.' months';break;
            case 'Y':$execTime = 'now +'.$num.' years';break;
            case 'H':$execTime = 'now +'.$num.' hours';break;
            case 'i':$execTime = 'now +'.$num.' minutes';break;
            case 'time':$execTime = $num;
        }
        if (strtoupper(substr(PHP_OS,0,3))==='WIN'){
            #todo windows下的定時任務改如何執行。
        }else {
            #其他系統
            $result = system("echo 'php think " . $command.time() . " " . $argv . "'|" . 'at ' . $execTime . '');
        }
        return $result;
    }
}

參考at命令可以知道

>at 時間
>任務命令
>ctrl+d <EOF>

而at的時間是兩種形式

1. now+1 days    #相對時間
2. 08:00pm       #絕對時間

所以上面代碼中的switch用來處理相對時間。
此代碼並不支持絕對時間加相對時間的處理,有待優化。比如:

$ at 08:00am + 1 days   #表示1天后早上八點

歡迎大家討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章