fsockopen() 函數以 Socket 模擬 HTTP 協議,作用是可以用來打開一個socket連接,可以進行類似真實的http操作,可用於向一個或者多個用戶發送多條模板消息等場景。
一、開啓 fsockopen 函數
第一步,打開PHP配置文件php.ini,查找 allow_url_fopen ,將其設置爲 on;
第二部,查找 extension=php_openssl.dll, 去掉前邊的分號 ‘;’;
第三部,如果是IIS 就重啓IIS,如果是apache 就重啓apache。
二、代碼實現(TP5.0框架下)
首先是發送多條微信模板消息的代碼(大致邏輯):
public function sendMessage()
{
ignore_user_abort(true);
set_time_limit(0);
//以下爲大致邏輯(不完整)
$msg = $_POST; //POST傳參
$message = getMessage($msg); //獲取消息內容
for($a=0;$a<count($message);$a++) {
$params = getParam; //拼裝發送消息的參數
$json_params = json_encode($params);
$url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token;
self::https_request($url, urldecode($json_params));
sleep(3); //給微信接口足夠的響應時間
}
//異步請求不打印報錯信息,將相關信息寫入文件內便於調試
//file_put_contents('./app/home/controller/A.txt',date('Y-m-d H:i:s',time())."\n".json_encode($message)."\n",FILE_APPEND);die;
}
以上代碼循環體內爲了保證正常調用微信接口,使用了 sleep() 函數,正常的同步請求顯然不能滿足要求
以下代碼封裝 fsockopen(完整代碼,實現異步就靠他了) ,一是建立一個一個socket連接,二是能夠傳參(POST)
public function doRequest($url, $param=array())
{
$urlInfo = parse_url($url);
$host = $urlInfo['host'];
$path = $urlInfo['path'];
$query = isset($param)? http_build_query($param) : '';
$port = 80;
$errno = 0;
$errstr = '';
$timeout = 60;
$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
$out = "POST ".$path." HTTP/1.1\r\n";
$out .= "host:".$host."\r\n";
$out .= "content-length:".strlen($query)."\r\n";
$out .= "content-type:application/x-www-form-urlencoded\r\n";
$out .= "connection:close\r\n\r\n";
$out .= $query;
fputs($fp, $out);
fclose($fp);
}
接下來就是入口文件,用於設置參數調用 doRequest() 函數實現異步請求
public function message($param) {
$url = 'http://www.xxx.com/yyy/zzz/sendMessage';
$this->doRequest($url, $param);
}