↓ 快轉到主要內容
Schedule 任務排程,讓Laravel 自動執行排定任務
技術文章Laravel

Schedule 任務排程,讓Laravel 自動執行排定任務

Posted by Alvin Chen on

Schedule 任務排程,讓Laravel 自動執行排定任務

·991 字·2 分鐘
作者
Alvin Chen
相信寫 Code 可以改變世界

Schedule 任務排程可以在很多種情況下使用到,比如說需要定期檢查某件事情完成與否,或扯定期將資料送往另一台伺服器

又或者最常見的將電子報寄送,都是透過這種排成任務的方式來執行

參考文件 :https://kejyuntw.gitbooks.io/laravel-5-learning-notes/services/scheduling/services-scheduling-README.html

laravel schedule

基本概念
#

對Laravel 還不是很熟悉的朋友請先看過以下文章喔

Composer 幫PHP套件找一個家

用Laravel 來建立你的第一個網站

首先,最基本的觀念是透過作業系統的定期排程工作來完成事件的觸發

在windows上可以用排程工作設定需要定期執行哪個檔案(通常可以寫成.bat)

在linux上可以透過

crontab -e

來編輯需要排成的工作指令,舉例

# 每天凌晨 3 點做資料備份
0 3 * * * /usr/bin/php /home/document/project/artisan cronjob:backup

值得注意的是,前面0 3 跟 * 代表的是時間,分別說明如下

  • 分(0-59)
  • 時(0-23)
  • 每個月第幾天(1-31)
  • 月份(1-12)
  • 每週的第幾天(0-6),0代表星期日其他依序

參考範例

# 每小時的第 18 分鐘執行
18 * * * *

# 8 點 10 分執行
10 8 * * *

# 8 點的每分鐘執行一次(共執行 60 次)
* 8 * * *

# 在每個禮拜二每小時的第 18 分鐘執行
18 * * * 2

# 你也可以每隔一段時間去執行 crontab
# 如果我們每 15 分鐘要去執行,你可以用這樣的格式 */15
# 這樣的意思是將分鐘數,切割成(除以)每 15 分鐘執行
*/15 * * * *

# 每 2 小時執行
0 */2 * * *

# 每 2 小時又 20 分鐘執行
*/20 */2 * * *

Larvel 實作
#

透過作業系統排程每分鐘執行 schedule:run 指令

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

舉例說明
#

我們將要排程的工作寫在app/Console/Command/test.php

<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use DB;

class TestLog extends Command
{
    // 命令名稱
    protected $signature = 'test:insert';

    // 說明文字
    protected $description = '[測試] 寫入資料庫';

    public function __construct()
    {
        parent::__construct();
    }

    // Console 執行的程式
    public function handle()
    {
        DB::table('log')
         ->insert([
          'time' => date('Y-m-d H:i:s')
         ])
    }
}

重點 :需要執行工作的地方寫在handle()中

以上設定完成之後可以透過指令直接執行

php artisan test:insert

接著要在laravel中定義此排程工作,編輯檔案 app/Console/Command/Kernal.php

大略會長成這樣子

<?php

namespace App\Console;

use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;

class Kernel extends ConsoleKernel
{
    // 定義應用程式的 Artisan 指令
    protected $commands = [
        \App\Console\Commands\test::class,
    ];

    // 定義應用程式的排程
    protected function schedule(Schedule $schedule)
    {
        // 每分鐘執行 Artisan 命令 test:Log
        $schedule->command('test:insert')->everyMinute();
    }
}

接著就會在資料庫中看到每分鐘記錄下來的資料了

避免重複執行
#

有些排程工作可能需要一點時間才能做完,修改$schedule指令可以避免工作還沒完成又再次進入工作

$schedule->command('test:insert')->withoutOverlapping();