下面是寫好的示例前端交互頁面,主要是列表頁面,編輯頁面。php
主要交互有:前端
1 開啓定時任務進程
2 關閉定時任務進程
3 新增一項定時任務
4 編輯已有的定時任務
5 刪除定時任務
6 開始一項定時任務
7 中止一項定時任務linux
定時任務分兩種:git
1 執行一次
2 循環執行github
定時任務執行的內容:web
定時任務執行的內容其實仍是一個http請求。 經過定時的方式,指定時間執行或者循執行。ajax
示例代碼是基於Laravel,Alpaca-spa框架編寫,而且做爲 ‘Alpaca-Spa-Laravel後臺管理平臺’的一個模塊兒集成於系統中。shell
內容 | 說明 | 地址 |
---|---|---|
Alpaca-Spa | 主頁 | http://www.tkc8.com |
Alpaca-Spa-Laravel | 後臺管理端 | http://full.tkc8.com |
Alpaca-Spa-Sui | 手機端sui | http://full.tkc8.com/app |
oschina | 代碼 | http://git.oschina.net/cc-sponge/Alpaca-Spa-Laravel |
github | 代碼 | https://github.com/big-sponge/Alpaca-Spa-Laravel |
定時精確時間不低於1秒。web服務重啓、或者php重啓。該定時任務不會自動重啓。json
用PHP實現定時任務(非linux-shell方式,與操做系統平臺無關),主要兩個技術點:瀏覽器
1)PHP後臺進程
2)PHP異步處理
通常狀況,用命令行能夠開啓一個php後臺進程。而在瀏覽器中經過HTTP請求一個php處理,會由於瀏覽器關閉,或者請求超時,使得後臺的php處理中斷。可是php提供了兩個方法能夠會忽略瀏覽器關閉、請求超時:
ignore_user_abort(true); // 忽略客戶端斷開 set_time_limit(0); // 設置執行不超時
所以,咱們可使用這兩個函數從瀏覽器以HTTP請求的方式開啓一個php後臺進程。
php語言自己沒有能夠跨平臺好用異步處理方法,可是能夠經過curl或者fsockopen建立一個請求來實現異步處理。這裏咱們用fsockopen方法實現:
$fp = fsockopen("$ip", $port, $errno, $errstr,1); if (!$fp) { return 'worker error:'."$errstr ($errno)<br />\n"; } else { $out = "POST $url HTTP/1.1\r\n"; $out .= "Host: $ip\r\n"; $out .= "Content-Type:application/x-www-form-urlencoded; charset=UTF-8\r\n"; $out .= "Content-Length: " . strlen($postData) . "\r\n"; $out .= "Connection: close\r\n"; $out .="\r\n"; $out .=$postData; fputs($fp, $out); fclose($fp); }
爲了在前端界面方便控制定時任務的開啓關閉,新增、編輯、刪除,查看執行狀態。 同時也能夠添加權限控制。 主要有8個操做接口(下面是以Laravel 路由示例):
1 查看定時任務進程狀態
2 開始定時任務進程
3 中止定時任務進程
4 添加,或者編輯定時任務
5 設置定時任務狀態
6 獲取指定定時任務明細
7 刪除定時任務
8 獲取定時任務列表
/* crontab - status 查看定時任務守護進程狀態 */ Route::any('crontab/status', "CrontabController@status"); /* crontab - start 開始定時任務 */ Route::any('crontab/start', "CrontabController@start"); /* crontab - stop 中止定時任務守護進程*/ Route::any('crontab/stop', "CrontabController@stop"); /* crontab - editTask 添加,或者編輯定時任務*/ Route::any('crontab/editTask', "CrontabController@editTask"); /* crontab - changeTaskStatus 設置定時任務狀態 */ Route::any('crontab/changeTaskStatus', "CrontabController@changeTaskStatus"); /* crontab - getIndexTask 獲取指定定時任務 */ Route::any('crontab/getIndexTask', "CrontabController@getIndexTask"); /* crontab - removeTask 刪除定時任務 */ Route::any('crontab/removeTask', "CrontabController@removeTask"); /* crontab - listTask 獲取定時任務列表 */ Route::any('crontab/listTask', "CrontabController@listTask");
完整的類代碼以下:
<?php namespace App\Modules\Manage\Controllers; use Crontab\Library\Crontab\AlpacaCrontab; use Crontab\Library\Crontab\AlpacaDaemon; use Crontab\Library\Crontab\AlpacaWorker; use App\Modules\Manage\Controllers\Base\BaseController; use App\Common\Code; use App\Common\Msg; /** * 定時任務管理控制器 * @author Chengcheng * @date 2016-10-19 15:50:00 */ class CrontabController extends BaseController { /** * 設置不須要登陸的的Action,不加Action前綴 * @author Chengcheng * @date 2016年10月23日 20:39:25 * @return array */ protected function noLogin() { return []; } /** * 設置不須要權限驗證的Action,不加Action前綴 * @author Chengcheng * @date 2016年10月23日 20:39:25 * @return array */ protected function noAuth() { // 如下Action不須要角色權限 return []; } /** * 查看定時任務守護進程狀態 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function status() { //查看守護進程狀態 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = AlpacaDaemon::daemon()->status(); //返回結果 return $this->ajaxReturn($result); } /** * 開始定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function start() { //異步開啓守護進程 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = AlpacaWorker::worker()->action(['REQUEST_URI' => "/crontab/index/start"]); //返回結果 return $this->ajaxReturn($result); } /** * 中止定時任務守護進程 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function stop() { //中止守護進程 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = AlpacaDaemon::daemon()->stop(); //返回結果 return $this->ajaxReturn($result); } /** * 添加,或者編輯定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function editTask() { /* * 1 獲取輸入參數 * BEGIN_TIME 開始時間 * END_TIME 結束時間 * INTERVAL 時間間隔 * NAME 名稱 * STATUS 狀態 1-ENABLED, 2-DISABLE * TASK_TYPE 類型 1-ONCE, 2-LOOP * ACTION 要執行的Action * INDEX 索引,null或者0時候,表示新建 * */ $this->requestData['NAME'] = $this->input('NAME', null); $this->requestData['BEGIN_TIME'] = $this->input('BEGIN_TIME', null); $this->requestData['END_TIME'] = $this->input('END_TIME', null); $this->requestData['INTERVAL'] = $this->input('INTERVAL', null); $this->requestData['TASK_TYPE'] = $this->input('TASK_TYPE', '1'); $this->requestData['ACTION'] = $this->input('ACTION', null); $this->requestData['STATUS'] = $this->input('STATUS', '2'); $this->requestData['INDEX'] = $this->input('INDEX', null); $this->requestData['LAST_TIME'] = $this->input('LAST_TIME', null); //2 檢查參數 if (empty($this->requestData['BEGIN_TIME'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'BEGIN_TIME'); return $this->ajaxReturn($result); } if ($this->requestData['TASK_TYPE'] == 2 && empty($this->requestData['END_TIME'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'END_TIME'); return $this->ajaxReturn($result); } if (empty($this->requestData['ACTION'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'ACTION'); return $this->ajaxReturn($result); } if ($this->requestData['TASK_TYPE'] == 2 && empty($this->requestData['INTERVAL'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'INTERVAL'); return $this->ajaxReturn($result); } //3 設置結束時間 $now = date('Y-m-d H:i:s', time()); $nextTime = date('Y-m-d H:i:s', strtotime($this->requestData['INTERVAL'], strtotime($this->requestData['BEGIN_TIME']))); if ($this->requestData['TASK_TYPE'] == "1" || strtotime($now) < strtotime($this->requestData['BEGIN_TIME'])) { $nextTime = $this->requestData['BEGIN_TIME']; } //4 建立任務 $task = array( 'NAME' => $this->requestData['NAME'], //NAME 'STATUS' => $this->requestData['STATUS'], // 1-ENABLED, 2-DISABLE 'TYPE' => $this->requestData['TASK_TYPE'], // 1-ONCE, 2-LOOP 'INTERVAL' => $this->requestData['INTERVAL'], //year(年),month(月),hour(小時)minute(分),second(秒) 'BEGIN_TIME' => $this->requestData['BEGIN_TIME'], //開始時間 'NEXT_TIME' => $nextTime, //下次執行時間 'LAST_TIME' => $this->requestData['LAST_TIME'], //上次執行時間 'ACTION' => $this->requestData['ACTION'], //執行的ACTION 'END_TIME' => $this->requestData['END_TIME'], //截止時間2 ); //5 判斷是新建仍是修改 if (empty($this->requestData['INDEX'])) { //新建 $info = AlpacaCrontab::crontab()->addTask($task); } else { $this->requestData['INDEX'] -= 1; $info = AlpacaCrontab::crontab()->editTask($this->requestData['INDEX'], $task); } //5 返回結果 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = $info; return $this->ajaxReturn($result); } /** * 設置定時任務狀態 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function changeTaskStatus() { /* * 1 獲取輸入參數 * STATUS 狀態 1-ENABLED, 2-DISABLE * INDEX 索引 * */ $this->requestData['STATUS'] = $this->input('STATUS', '2'); $this->requestData['INDEX'] = $this->input('INDEX', null); //2 檢查參數 if (empty($this->requestData['STATUS'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'STATUS'); return $this->ajaxReturn($result); } if (empty($this->requestData['INDEX'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'INDEX'); return $this->ajaxReturn($result); } //3 修改狀態 $this->requestData['INDEX'] -= 1; $data = AlpacaCrontab::crontab()->editTaskStatus($this->requestData['INDEX'], $this->requestData['STATUS']); //4 返回結果 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = $data; return $this->ajaxReturn($result); } /** * 查找單條定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function getIndexTask() { /* * 1 獲取輸入參數 * INDEX 索引 * */ $this->requestData['INDEX'] = $this->input('INDEX', null); //2 檢查參數 if (empty($this->requestData['INDEX'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'INDEX'); return $this->ajaxReturn($result); } //3 刪除 $this->requestData['INDEX'] -= 1; $data = AlpacaCrontab::crontab()->getIndexTask($this->requestData['INDEX']); //4 返回結果 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = $data; return $this->ajaxReturn($result); } /** * 刪除定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function removeTask() { /* * 1 獲取輸入參數 * INDEX 索引 * */ $this->requestData['INDEX'] = $this->input('INDEX', null); //2 檢查參數 if (empty($this->requestData['INDEX'])) { $result["code"] = Code::SYSTEM_PARAMETER_NULL; $result["msg"] = sprintf(Msg::SYSTEM_PARAMETER_NULL, 'INDEX'); return $this->ajaxReturn($result); } //3 刪除 $this->requestData['INDEX'] -= 1; $data = AlpacaCrontab::crontab()->removeTask($this->requestData['INDEX']); //4 返回結果 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = $data; return $this->ajaxReturn($result); } /** * 查看定時任務列表 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function listTask() { //查找 $data['task'] = AlpacaCrontab::crontab()->listTask(); $data['total'] = count($data['task']); $data['status'] = AlpacaDaemon::daemon()->status(); //返回結果 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = $data; return $this->ajaxReturn($result); } }
使用 ignore_user_abort(true); set_time_limit(0); 能夠從瀏覽器開啓一個php後臺進程。爲了不出現多個後臺進程,須要藉助一個配置來標識該後臺進程是否已經啓動。
{"code":"1001","message":"Stop at:2017-02-24 11:29:43"}
當code是1001時候,表示後臺進程未啓動,這時經過http請求開啓後臺進程時,正常啓動
當code是1000時候,表示後臺進程已經啓動,這時經過http請求開啓後臺進程時,不作任何操做,覺得進程已經啓動
當開啓後臺進程的請求到達後臺時候,讀取配置文件,若是code是1001,則啓動進程,而且設置code爲1000,保存配置文件。
當關閉後臺進程的請求到達後臺時候,讀取配置文件,設置code爲1001,保存配置文件。
後臺進程在運行時候,每隔一秒讀取配置文件,判斷code狀態,若是是1001,則結束執行; 若是是1000,則繼續執行
完整類的代碼以下:
<?php namespace Crontab\Library\Crontab; /** * 守護進程 * @author Chengcheng * @date 2016年10月21日 17:04:44 */ class AlpacaDaemon { private $daemon_json = __DIR__ . '/deamon.json'; private static $instance; private $events = []; public static function daemon() { return self::getInstance(); } private static function getInstance() { if(!self::$instance){ self::$instance = new self(); self::$instance->daemon_json = base_path('storage') . '/crontab/deamon.json'; } return self::$instance; } public function setDaemon($daemon_json) { $this->daemon_json = $daemon_json; return $this; } public function setEvents(array $events) { $this->events = $events; return $this; } public function status() { $data = json_decode(file_get_contents($this->daemon_json),true); if(empty($data)){ $data = array(); } return $data; } public function stop() { $data =new \stdClass(); $data->code="1001"; $data->message="Stop at:".date("Y-m-d H:i:s" ,time()); file_put_contents($this->daemon_json,json_encode($data),LOCK_EX); $result["result_code"] = "1"; $result["result_message"] = "操做成功"; return $result; } public function start() { $data = json_decode(file_get_contents($this->daemon_json) , true); if(empty($data)){ $data['code']="1001"; } if($data['code'] == "1000" ){ //die("Error - exit, Already running !"); return; } $data['code']="1000"; $data['message']="Start"; file_put_contents($this->daemon_json,json_encode($data),LOCK_EX); ignore_user_abort(true); // 忽略客戶端斷開 set_time_limit(0); // 設置執行不超時 while(true){ $data = json_decode(file_get_contents($this->daemon_json) , true); if(empty($data) || empty($data['code']) || $data['code'] == "1001" ){ break; } if(!empty($this->events)){ foreach ($this->events as $e){ $e(); } } $data['message'] = date("Y-m-d H:i:s" ,time())." : Working ..."; file_put_contents($this->daemon_json, json_encode($data), LOCK_EX); sleep(1); } $this->stop(); } }
完整類的代碼以下:
<?php namespace Crontab\Library\Crontab; class AlpacaWorker { private static $instance; private $accessToken = ''; public static function worker() { return self::getInstance(); } private static function getInstance() { if(!self::$instance){ self::$instance = new self(); self::$instance->accessToken= 'VyKfohBbwlkTOqp2jvIWPW92'; } return self::$instance; } public function action(array $worker = null) { //獲取參數 $ip = empty($worker['SERVER_ADDR']) ? $_SERVER['SERVER_NAME'] : $worker['SERVER_ADDR']; //服務器IP地址 $port = empty($worker['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : $worker['SERVER_PORT']; //服務器端口 $url = empty($worker['REQUEST_URI']) ? '/' :$worker['REQUEST_URI']; //服務器URL $data = empty($worker['REQUEST_DATA']) ? '' :$worker['REQUEST_DATA']; //請求參數 //格式化請求參數 $postData = ""; $needChar = false; if(is_array($data)){ foreach($data as $key => $val) { $postData .= ($needChar ? "&" : "") . urlencode($key) . "=" . urlencode($val); $needChar = true; } }else{ $postData = $data; } $url=$url."?accessToken=".$this->accessToken; //使用fsockopen方式異步調用action $fp = fsockopen("$ip", $port, $errno, $errstr,1); if (!$fp) { return 'worker error:'."$errstr ($errno)<br />\n"; } else { $out = "POST $url HTTP/1.1\r\n"; $out .= "Host: $ip\r\n"; $out .= "Content-Type:application/x-www-form-urlencoded; charset=UTF-8\r\n"; $out .= "Content-Length: " . strlen($postData) . "\r\n"; $out .= "Connection: close\r\n"; $out .="\r\n"; $out .=$postData; fputs($fp, $out); fclose($fp); } return 'worker success!'; } }
定時任務處理類 主要是實現新增、編輯、刪除定時任務,執行定時任務要處理的方法
定時任務的信息以json格式存放在下面的配置文件中
[{"NAME":"\u6d4b\u8bd5\u5b9a\u65f6\u4efb\u52a12","STATUS":"2","TYPE":"1","INTERVAL":"5 second","BEGIN_TIME":"2017-02-21 11:55:00","NEXT_TIME":"2017-02-21 11:55:00","LAST_TIME":null,"ACTION":"\/main\/crontab\/index2","END_TIME":"2017-02-10 15:55:00"},{"NAME":"TEST - log","STATUS":"2","TYPE":"2","INTERVAL":"5 second","BEGIN_TIME":"2017-08-10 09:00:53","NEXT_TIME":"2017-08-10 09:59:00","LAST_TIME":"2017-08-10 09:58:55","ACTION":"\/crontab\/task\/test","END_TIME":"2017-08-11 09:25:53"}]
主要的字段爲:
INDEX 索引
BEGIN_TIME 開始時間
END_TIME 結束時間
INTERVAL 時間間隔
NAME 名稱
STATUS 狀態 1-ENABLED, 2-DISABLE
TASK_TYPE 類型 1-ONCE, 2-LOOP
ACTION 要執行的Action
類中主要有7個方法:
listTask() 查看定時任務列表
addTask() 添加定時任務
editTask() 編輯定時任務
editTaskStatus() 編輯定時任務狀態
getIndexTask() 獲取指定定時任務信息
removeTask() 刪除定時任務
doTask() 執行定時任務指定的任務
完整類的代碼以下:
<?php namespace Crontab\Library\Crontab; /** * 定時任務 * @author Chengcheng * @date 2016年10月21日 17:04:44 */ class AlpacaCrontab { //定時任務文件 private $task_json = __DIR__ .'/crontab.json'; //單例 private static $instance; //單例 public static function crontab() { return self::getInstance(); } //單例 private static function getInstance() { if(!self::$instance){ self::$instance = new self(); self::$instance->task_json = base_path('storage') . '/crontab/crontab.json'; } return self::$instance; } /** * 配置 * @author Chengcheng * @param array $crontab * @date 2016-10-23 20:34:00 * @return array */ public function setConfig($crontab) { $this->task_json = $crontab; return $this; } /** * 查看定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 * @return array */ public function listTask() { $tasks = json_decode(file_get_contents($this->task_json)); $i = 0; foreach ($tasks as $task) { $tasks[$i]->INTERVAL = $this->timeToStr($tasks[$i]->INTERVAL); $i++; } return $tasks; } /** * 添加定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 * @return array */ public function addTask($task) { $result["result_code"] = "1"; $result["result_message"] = "添加成功"; $tasks = json_decode(file_get_contents($this->task_json),true); $tasks[count($tasks)] = $task; file_put_contents($this->task_json, json_encode($tasks), LOCK_EX); return $result; } /** * 編輯定時任務 * @author Chengcheng * @param string $index * @param string $task * @date 2016-10-23 20:34:00 * @return array */ public function editTask($index,$task) { $result["result_code"] = "1"; $result["result_message"] = "修改爲功"; $tasks = json_decode(file_get_contents($this->task_json)); $tasks[$index] = $task; file_put_contents($this->task_json, json_encode($tasks), LOCK_EX); return $result; } /** * 編輯定時任務狀態 * @author Chengcheng * @param string $index * @param string $status * @date 2016-10-23 20:34:00 * @return array */ public function editTaskStatus($index,$status) { $result_data["result_code"] = "1"; $result_data["result_message"] = "修改狀態成功[".$status."]"; $tasks = json_decode(file_get_contents($this->task_json)); $tasks[$index]->STATUS = $status; file_put_contents($this->task_json, json_encode($tasks), LOCK_EX); return $result_data; } /** * 獲取定時任務 * @author Chengcheng * @param string $index * @date 2016-10-23 20:34:00 * @return array */ public function getIndexTask($index) { $result_data["result_code"] = "1"; $result_data["result_message"] = "獲取任務成功【".$index."】"; $tasks = json_decode(file_get_contents($this->task_json)); $result_data["result_data"] = $tasks[$index]; return $result_data; } /** * 刪除定時任務 * @author Chengcheng * @param string $index * @date 2016-10-23 20:34:00 * @return array */ public function removeTask($index) { $result_data["result_code"] = "1"; $result_data["result_message"] = "刪除任務【".$index."】成功"; $tasks = json_decode(file_get_contents($this->task_json)); array_splice($tasks, $index, 1); file_put_contents($this->task_json, json_encode($tasks), LOCK_EX); return $result_data; } /** * 執行定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 * @return array */ public function doTask() { $tasks = json_decode(file_get_contents($this->task_json) ,true); if(empty($tasks)){ return ;} $now = date('Y-m-d H:i:s',time()); foreach ($tasks as &$task){ if(empty($task['STATUS']) || empty($task['TYPE']) || empty($task['BEGIN_TIME']) || empty($task['ACTION']) ) { continue; } if($task['STATUS'] != 1) { continue; } if(!empty($task['END_TIME']) && strtotime($now)>=strtotime($task['END_TIME'])){ $task['NEXT_TIME']='END'; continue; } if($task['TYPE'] == 1 && empty($task['NEXT_TIME']) ) { continue; } if($task['TYPE'] == 2 && empty($task['INTERVAL']) ) { continue; } if(!empty($task['NEXT_TIME']) && $task['NEXT_TIME']=='END' ) { continue; } if($task['TYPE'] == 1 && (strtotime($now)>=strtotime($task['NEXT_TIME']))) { $task['LAST_TIME']= $now; $task['NEXT_TIME']='END'; $task['STATUS']=2; AlpacaWorker::worker()->action(['REQUEST_URI'=>"{$task['ACTION']}"]); continue; } if($task['TYPE'] == 2) { if(empty($task['NEXT_TIME'])){ $task['NEXT_TIME'] = $task['BEGIN_TIME']; } if(strtotime($now)>=strtotime($task['NEXT_TIME'])){ $task['LAST_TIME']= $now; $task['NEXT_TIME']= date('Y-m-d H:i:s',strtotime($task['INTERVAL'])); AlpacaWorker::worker()->action(['REQUEST_URI'=>"{$task['ACTION']}"]); } continue; } } file_put_contents($this->task_json, json_encode($tasks), LOCK_EX); return $tasks; } /** * 格式化時間 * @author Chengcheng * @param string $interval * @date 2016-10-23 20:34:00 * @return array */ private function timeToStr($interval) { $result = ""; if($interval != null && $interval != ""){ $temp = explode(" ", $interval); $iNumTemp = $temp[0]; $iType = $temp[1]; $iNum = str_replace("+", "", $iNumTemp); $str = ""; switch ($iType){ case "year": $str = "(年)"; break; case "month": $str = "(月)"; break; case "day": $str = "(日)"; break; case "hour": $str = "(小時)"; break; case "minute": $str = "(分)"; break; case "second": $str = "(秒)"; break; default: break; } $result = $iNum. $str; } return $result; } }
主要是爲了實現異步開啓後臺進程
<?php namespace Crontab\Controllers; use Crontab\Common\Code; use Crontab\Common\Msg; use Crontab\Controllers\Base\BaseController; use Crontab\Library\Crontab\AlpacaCrontab; use Crontab\Library\Crontab\AlpacaDaemon; use Crontab\Library\Crontab\AlpacaWorker; /** * index * @author Chengcheng * @date 2017-02-22 15:50:00 */ class IndexController extends BaseController { /** * 設置不須要登陸的的Action,不加Action前綴 * @author Chengcheng * @date 2016年10月23日 20:39:25 * @return array */ protected function withoutLoginActions() { } /** * 開始定時任務的守護進程 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function start() { //開始守護進程 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; //在守護進程中注入定時任務 $events = ['0'=>function(){ AlpacaWorker::worker()->action(['REQUEST_URI'=>"/crontab/index/task"]); }]; AlpacaDaemon::daemon()->setEvents($events); AlpacaDaemon::daemon()->start(); //返回結果 return $this->ajaxReturn($result); } /** * 中止定時任務的守護進程 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function stop() { //中止守護進程 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = AlpacaDaemon::daemon()->stop(); //返回結果 return $this->ajaxReturn($result); } /** * 執行定時任務 * @author Chengcheng * @date 2016-10-23 20:34:00 */ public function task() { //執行定時任務 $result['code'] = Code::SYSTEM_OK; $result['msg'] = Msg::SYSTEM_OK; $result['data'] = AlpacaCrontab::crontab()->doTask(); //返回結果 return $this->ajaxReturn($result); } }
以上是PHP實現定時任務的核心類與方法, 完整的代碼請參看代碼服務器中提供的源碼。
做者: Sponge
郵箱: 1796512918@qq.com
原文地址:https://www.jianshu.com/p/c68dba7736eb