在項目的開發(fā)過程中經(jīng)常會有定時任務(wù)的需求,例如按時自動處理訂單狀態(tài)或者需要做某個接口的隊列??墒荘HP本身對上述場景的支持并是不很好,雖然可以通過配置響應(yīng)時間的方法讓PHP進(jìn)程不結(jié)束,但從測試和易維護(hù)的角度來說,最實用的方案是通過服務(wù)器定時任務(wù)來實現(xiàn)。由于配置Linux定時任務(wù)會涉及到很多方面的知識,對于Linux不太熟的開發(fā)者容易望而卻步,本文就以最簡單的方式將這種方案實現(xiàn)落地,希望對大家有幫助。

編輯crontab文件
每個用戶都擁有自己的crontab文件,文件包含送交守護(hù)進(jìn)程的一系列指令,通常使用下面的命令對該文件進(jìn)行編輯:
> crontab -e
默認(rèn)的編輯器是vim,只需要記住按i可以對文本進(jìn)行編輯,使用上下左右箭頭調(diào)整光標(biāo)位置,按esc退出編輯,退出編輯后鍵入:wq對文件進(jìn)行保存即可,就像下面這樣:

定時的語法如下:
* * * * * /WWW/learnlinux/sometask.sh
分鐘 小時 日 月 星期 命令
上面的意思是,每1分鐘執(zhí)行一次sometask.sh。5個*號的位置代表的是執(zhí)行任務(wù)的時間,語法是這樣的:
“\*”代表所有,
“/”代表循環(huán)周期,
“-”代表從某個數(shù)字到某個數(shù)字的區(qū)間,
“,”分開幾個離散的數(shù)字
最簡單的寫法如下:
30 * * * * 代表每個小時的第30分鐘執(zhí)行一次
30 6 * * * 代表每天的6點30分執(zhí)行一次
30 6 15 * * 代表每個月的15號6點30分執(zhí)行一次
30 6 15 5 * 代表每年的5月15號6點30分執(zhí)行一次
也可以用星期表示,0代表周日:
30 6 * * 0 代表每個周日的6點30執(zhí)行一次
稍微復(fù)雜一點:
*/5 * * * * 代表每隔5分鐘執(zhí)行一次
30 6 */5 * * 代表每隔5天就在6點30分執(zhí)行一次
0 2-5 * * * 代表每天的2點到5點鐘的第0分鐘執(zhí)行一次
20,40 * * * * 代表每個小時的第20和第40分鐘執(zhí)行一次
創(chuàng)建可執(zhí)行文件
我們既然規(guī)定每分鐘執(zhí)行一次sometask.sh那么就到相應(yīng)的目錄下去創(chuàng)建該文件:
> cd /WWW/learnlinux/
> vim sometask.sh
這里使用vim創(chuàng)建文件,編輯方法上文中有,sometask.sh文件內(nèi)容如下:
#!/bin/sh
curl http://localhost/learnlinux/
該文件中第一行為固定寫法,第二行用于指定訪問的頁面URL,curl命令可以以GET的方式訪問后面的地址,注意:地址不需要添加引號。你可以將這里的URL修改為實際項目中需要被定時訪問的頁面。
案例中被訪問的頁面PHP代碼如下:
<?php
file_put_contents('timer.log', date('m-d H:i:s', time()).PHP_EOL, FILE_APPEND);
該頁面每次被訪問都會將當(dāng)前時間追加到同目錄的日志文件(timer.log)中,主要用于測試前面的代碼是否正常執(zhí)行。注意:需要給該目錄創(chuàng)建文件的權(quán)限。
上述文件創(chuàng)建成功之后,可以先執(zhí)行一次sh文件,測試頁面是否正常被訪問,之后再觀察timer.log文件被訪問的時間點是否是你所希望的。就像這樣:

再之后你就可以在頁面文件里處理你的業(yè)務(wù)邏輯了,測試的時候可以用
#注釋crontab文件。這樣,雖然PHP不支持定時任務(wù),但通過服務(wù)器技術(shù),今后再遇到需要自動處理狀態(tài)或者做接口隊列的項目就簡單很多了。
至于window服務(wù)器,請去下載各種現(xiàn)成的定時執(zhí)行程序:)