【PHP】PHP實現簡單的setTimeOut來完成非同步延時
阿新 • • 發佈:2019-02-17
一、需求來源。
- 開發微信公眾號時,當用戶關注我們的微訊號,我們需要傳送兩條不同型別的訊息給關注使用者。注意是不同型別。這麼說吧,要傳送Type1,Type2兩種訊息回覆給關注者。
- 其中關注這個事件,處理這個事件的流程如果傳送了其中1個型別的訊息,就無法傳送另外一種了。意思就是無法同時傳送兩種。類似於http請求,回覆一次就OK了,收到第一次的response,就結束了。
- 而且需求是另外的一種回覆訊息(Type2),必須要在主流程的訊息之後傳送。好在微信提供了介面——客服傳送介面,該介面可以主動給使用者傳送訊息。
二、實現上面的需求,並規範化。
//關注事件
case "subscribe" :
$result = $this->transmitNews($content);// 生成Type1的訊息
// 格式化生成Type2的訊息體
$result_other = sprintf("***?先註冊<a href='%s'>(點選註冊)</a>吧", $url);
$_arr = array(
'openid' => sprintf('%s', $this->fromUserName),// 格式化微信openid
'content' => $result_other,
);
$url = sprintf('%s/%s/%s' , APP_URL, APP, PubCCCCConf::DDDDDDDDDDD_URL);
// 利用nginx生成另外一個請求
LibUtil::makeRequest($url,
array('key' => PubCCCCConf::KKKKKKKKKK_KEY, 'cd_time' => 1, 'user_func' => 'ddddddddddMsg', 'json_str' => json_encode($_arr)), 1, 'POST');
break;
// 開始傳送Type1主體訊息
// 延時回撥
public function postAAAAAAAsync () {
$this->setOutType('json');
$key = $this->R('key');
$cd_time = $this->R('cd_time', 0, 'int');// 單位s
$user_func = $this->R('user_func', '', 'string');// 這個函式必須是這個類裡的函式
$json_str = $this->R('json_str', '', 'string', true, NULL);// 引數
// 防刷機制
if ( $key != PubCCCCConf::KKKKKKKKKK_KEY ) {
$this->out = array('code' => 3, 'data' => array(), 'msg' => '沒有許可權');
return;
}
// 最長時間300s
if ( empty($user_func) || $cd_time >= 300 || !PubValidate::isJson($json_str)) {
$this->out = array('code' => 2, 'data' => array(), 'msg' => '引數錯誤');
return;
}
$args = json_decode($json_str, true);
$args['cd_time'] = $cd_time;
call_user_func(array('Ctl*****',$user_func), $args);
$this->out = array('code' => 1, 'data' => array(), 'msg' => 'SUCCESS');
}
// 這個最好是命名為私有函式
private function ddddddddddMsg($param) {
// 具體的處理邏輯
sleep($param['cd_time']);// 延時
...
}
1、我們看上面的程式碼,第1片程式碼中邏輯是,在正式傳送Type1類訊息時,先利用nginx生成另外一個請求,在另外一個請求中,延時cd_time時間,處理。
2、注意$key (防刷)、call_user_func的使用。
3、部分函式名、變數名醜陋是為了模糊處理。