這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰php
定時任務在實際業務中常常用到,例如未支付訂單超時取消,定時清理日誌等。上一個項目是一個自動售貨機,須要調用物聯網設備,偶爾會有信號很差致使設備啓動信號發出以後,接收不到設備啓動信息,須要主動查詢設備啓動狀況,啓動成功將訂單標記成功,失敗的須要給用戶退款。shell
初期是作了一個http接口,經過crontab定時調用觸發,按期處理異常訂單,可是當訂單體量增大,任務執行時間增加,有時候會阻塞業務。後來改爲了php命令行執行,知足了業務需求。數組
crontab 是用來讓使用者在固定時間或固定間隔執行程序之用,也就是相似使用者的時程表。markdown
定義格式以下:app
minute hour day month week command
複製代碼
minute
分鐘,範圍0-59。hour
小時,範圍0-23。day
每個月幾號,範圍1-31。month
月份,範圍1-12。week
一週的第幾天,範圍0-7,0和7都是週日。command
執行的命令。當 minute
爲 5
表示每五分鐘執行一次 command
;當值爲 *
表示每一個時間單位都執行一次;能夠用,
隔開多個值,例如2,5,10
表示設定時間內的2分,5分,10分執行命令;能夠用-
隔開兩個值,例如10-20
設定時間內的第10分開始到20分結束每分鐘執行一次命令;*/15
表示每15分鐘執行一次命令。其他單位設置方式相同。composer
舉例:post
天天上午10點-12點,每半個小時執行一次命令測試
*/30 10-12 * * *
複製代碼
每一年的5月1日和10月1日凌晨2點執行一次命令ui
0 2 1 5,10 *
複製代碼
composer create-project topthink/think command-demo
複製代碼
cd command-demo
進入項目目錄,接着執行 php think
,若是沒有配置php環境變量可使用絕對路徑,例如/usr/local/php/bin/php think
。若是打印出相似以下內容說明項目安裝成功。this
php think make:command OrderCheckCommand ordercheck
複製代碼
上面命令的意思是在app/command/
目錄下 建立一個OrderCheckCommand.php
php類文件,命令名稱叫作ordercheck
。
找到config/console.php
文件,添加以下代碼:
<?php
return [
// 指令定義
'commands' => [
'ordercheck' => 'app\command\OrderCheckCommand'
],
];
複製代碼
試着執行命令 php think ordercheck
若是看到以下輸出,則命令建立成功。
打開app/command/OrderCheckCommand.php
其中configure
方法是對指令的配置
setName
設置指令名稱;
setDescription
設置指令描述內容;
addArgument
設置指令參數;
addOption
設置指令選項。
execute
當執行命令時會執行execute
中邏輯。
建立一個僞需求:指令接收一個訂單狀態參數,其中1是異常訂單,需校驗訂單實際狀態,2只查詢失敗訂單,給用戶退款;接收一個省份選項,若是輸入省份則只處理某個省份的訂單。
修改代碼以下:
class OrderCheckCommand extends Command {
protected function configure() {
// 指令配置
$this->setName('ordercheck')
// Argument::OPTIONAL->可選參數 Argument::REQUIRED->必填參數 Argument::IS_ARRAY->數組參數
->addArgument('status', Argument::OPTIONAL, '訂單狀態', 1)
->addOption('province', 'p', Option::VALUE_REQUIRED, '訂單所屬省份', 'beijing')
->setDescription('the ordercheck command');
}
protected function execute(Input $input, Output $output) {
$status = intval($input->getArgument('status'));
$statusText = $status == 1 ? '訂單狀態爲異常訂單,進行訂單實際狀態校驗' : '訂單狀態失敗訂單,退款給用戶';
if ($input->hasOption('province')) {
$pre = '處理' . $input->getOption('province') . '訂單;';
} else {
$pre = '處理全國訂單;';
}
// 記錄執行日誌
Log::info($pre . $statusText);
// 指令輸出
$output->writeln($pre . $statusText);
}
}
複製代碼
addArgument
接收四個參數,分別是名稱、類型、描述、默認值;類型可選值分別爲 Argument::OPTIONAL(可選參數)
、Argument::REQUIRED(必填參數)
、Argument::IS_ARRAY(數組參數)
。
addOption
接收五個參數,分別是選項名稱、別名(簡寫選項名)、類型、描述、默認值,其中類型可選值分別是Option::VALUE_NONE(無需傳值)
、Option::VALUE_REQUIRED(必須傳值)
、Option::VALUE_OPTIONAL(可選傳值)
、Option::VALUE_IS_ARRAY(傳數組值)
。
假設須要一個定時任務,每2分鐘查詢省份爲beijing
的失敗訂單給用戶退款,咱們須要執行的命令就是:
php think ordercheck 2 -p beijing
複製代碼
當命令寫到crontab中須要寫項目的絕對路徑,最終crontab寫入內容以下:
*/2 * * * * php /home/www/command-demo/think ordercheck 2 -p beijing
複製代碼
首先執行crontab -e
,添加上面內容,保存。
接着執行systemctl restart crond.service
,重啓crontab。
等待幾分鐘以後查看日誌,看命令是否執行。