class XcxWeChat
{
//微信公众号身份的唯一标识
//微信公众平台里的APPID
protected $appId = 'wx056xxxx1479a02';
//微信公众号里面的SECRET
protected $appSecret = '4c112bf5a7xxxxxxxcde5451f6508a7c';
//图片存储路径
protected $imageDir = 'WeChat';
protected $token = '782xxx713';
//用户获取小程序二维码
public function getUnlimited($user){
$redis = new Redis();
$accessToken = $redis->get('access_token_xcx');
// 判断$access_token是否存在
if(!$accessToken){
if(!$this->getAccessToken()){
Log::write('getAccessToken()接口异常','error');
apiJson(500,'access_token生成失败');
}else{
$accessToken = $redis->get('access_token_xcx');
}
}
$redis->close();
$data['scene'] = $user;
$url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$accessToken;
$result = doPostCurl($url,json_encode($data));
return $this->decryptUnlimited($result);
}
//二维码图片数据处理
private function decryptUnlimited($result)
{
//判断是否是 json格式
if(is_null(json_decode($result))){
//不是json数据 有数据流 json_decode($codeinfo)返回值为 null
//图片名称
$picName = mt_rand(1,10000).substr(uniqid(), 6, 13).'.jpg';
$fileDir = './images/' . $this->imageDir;
if (!file_exists($fileDir)){
mkdir($fileDir,0777);
}
$filePath = $fileDir . '/' . $picName;
$jpg = $result;//得到post过来的二进制原始数据
$file = fopen($filePath,"w");//创建件准备写入,文件名xcxcode/wxcode1.jpg为自定义
fwrite($file,$jpg);//写入
fclose($file);//关闭
apiJson(200,'获取成功',ltrim($filePath,'.'));
}else{
Log::write('二维码数据异常','error');
apiJson(500,'二维码数据异常');
}
}
//获取openid、session_key
public function getOpenIdAndSessionKey($code)
{
$url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $this->appId . "&secret=" . $this->appSecret . "&js_code=" . $code . "&grant_type=authorization_code";
$result = json_decode($this->GetCurl($url),true);
return $result;
}
//加密openId、sessionKey,并存入缓存
public function encryptedOpenIdAndSessionKey($openId,$sessionKey){
$key = md5(sha1($openId) . md5($sessionKey) . mt_rand(10000,99999));
$value = $openId . '|' . $sessionKey;
$redis = new Redis();
$redis->set($key,$value,7200);
$redis->close();
return $key;
}
//解密手机
public function decryptTelephone($iv,$encryptedData,$sessionKey){
$aesKey=base64_decode($sessionKey);
if (strlen($iv) != 24) {
LOG::write('非合法解密向量','error');
apiJson(500,'非合法解密向量');
}
$aesIV=base64_decode($iv);
$aesCipher=base64_decode($encryptedData);
$result=openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
$dataObj=json_decode($result);
if($dataObj == NULL)
{
LOG::write('解密数据异常','error');
apiJson(500,'解密数据异常')->getContent();
}
if(!empty($dataObj->phoneNumber)){
$telephone = $dataObj->phoneNumber;//得到手机号
}else{
$telephone = '';
}
return $telephone;
}
//获取AccessToken
public function getAccessToken()
{
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appId."&secret=".$this->appSecret;
$data = json_decode($this->getCurl($url));
$redis = new Redis();
$result = $redis->set('access_token_xcx',$data->access_token,$data->expires_in);
$redis->close();
return $result;
}
//消息推送配置
public function pushCheck()
{
$echoStr = request()->param("echostr");
//valid signature , option
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
//校验推送配置
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = $this->token;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if ($tmpStr == $signature ) {
return true;
} else {
return false;
}
}
//小程序消息通知模板
public function xcxNotifyTemplate($data)
{
$template = [
"touser"=>$data['openId'],
"template_id"=>$data['templateId'],
"form_id"=>$data['formId'],
"data"=>$data['data']
];
return $template;
}
//通知推送
public function notifySend($data){
//该代码段可放封装里面,也可以写在控制器,有待考量。
$redis = new Redis();
$accessToken = $redis->get('access_token_xcx');
//判断$access_token是否存在
if(!$accessToken){
if(!$this->getAccessToken()){
Log::write('getAccessToken()接口异常','error');
$redis->close();
return false;
}else{
$accessToken = $redis->get('access_token_xcx');
}
}
$redis->close();
//发送模板消息
$rData = $this->postCurl("https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=".$accessToken,json_encode($data));
$rData = json_decode($rData,true);
if($rData['errcode'] == 0){
return true;
}else{
Log::write($rData,'error');
return false;
}
}
//获取用户formId
public function getFormId($openId)
{
$redis = new Redis();
//获取用户存在redis OR 缓存里面的 formId数组$openidFormIds
$openIdFormIds = $redis->get($openId.'formIds');
if(!empty($openIdFormIds)){
$formId = array_shift($openIdFormIds);
$remainTime = $redis->ttl($openId.'formIds');
//设置剩余时间
if($remainTime>0){
$redis->set($openId . 'formIds', $openIdFormIds, $remainTime);
}
$redis->close();
return $formId;
}else{
Log::write($openId.':用户不存在formId可使用','error');
return false;
}
}
//存储用户formId
public function saveFormId($openId,$formIdList)
{
//判断头文件中是否有formId传过来
if(!empty($formIdList)){
$redis = new Redis();
//获取用户存在redis OR 缓存里面的 formId数组$openidFormIds
$openidFormIds = $redis->get($openId.'formIds');
if(empty($openidFormIds)){
$openidFormIds = array();
}
foreach ($formIdList as $formId){
array_push($openidFormIds,$formId->value);
}
//将数组$formIdArr存入redis OR 缓存里面
$redis->set($openId.'formIds',$openidFormIds,86400*7);
$redis->close();
}
}
//get请求
private function getCurl($url)
{
$curl = curl_init();
// 使用curl_setopt()设置要获取的URL地址
curl_setopt($curl, CURLOPT_URL, $url);
// 设置是否输出header
curl_setopt($curl, CURLOPT_HEADER, false);
// 设置是否输出结果
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 设置是否检查服务器端的证书
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
// 使用curl_exec()将CURL返回的结果转换成正常数据并保存到一个变量
$data = curl_exec($curl);
// 使用 curl_close() 关闭CURL会话
if($data){
//关闭URL请求
curl_close($curl);
return $data;
}else{
$error = curl_error($curl);
Log::write('XcxWeChat:post出错'.$error);
curl_close($curl);
return false;
}
}
private function postCurl($url,$post_data)
{
//初始化
$curl = curl_init();
//设置超时
curl_setopt($curl,CURLOPT_TIMEOUT,30);
//设置抓取的url
curl_setopt($curl, CURLOPT_URL, $url);
//设置头文件的信息作为数据流输出
// curl_setopt($curl, CURLOPT_HEADER, 1);
// 设置是否输出header
curl_setopt($curl, CURLOPT_HEADER, false);
//设置获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
// 设置是否检查服务器端的证书
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
//设置post方式提交
curl_setopt($curl, CURLOPT_POST, 1);
//设置post数据
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
//执行命令
$data = curl_exec($curl);
if($data){
//关闭URL请求
curl_close($curl);
return $data;
}else{
$error = curl_error($curl);
Log::write('XcxWeChat:post出错'.$error);
curl_close($curl);
return false;
}
}
}
代码有待改进,可自行调整,欢迎大佬们给意见