appid = $appid;
$this->secret = $secret;
$this->valid();
$this->getaccess_token();
}
public function valid(){ //验证token
$echoStr = input('echostr');
if($this->checkSignature()){
echo $echoStr;
//exit;
}
}
private function checkSignature(){ //验证token
$signature = input("signature");
$timestamp = input("timestamp");
$nonce = input("nonce");
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
public function getaccess_token(){ //获取access_token 用redis来做中间token存储
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
$token = $redis->get($this->appid);
if($token){
$this->access_token = $token;
}else{
$token_access_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $this->appid . "&secret=" . $this->secret;
$res = file_get_contents($token_access_url); //获取文件内容或获取网络请求的内容
$result = json_decode($res, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量
if(isset($result['access_token'])){
//把access_token存入redis用 access_token expires_in 过期时间 来做过期时间
$result['expires_in'] = 3600;
$redis->setex($this->appid,$result['expires_in'],$result['access_token']);
$this->access_token = $result['access_token'];
}else{
$this->access_token = '';
}
}
}
//获取粉丝openid 一次最多拉取 1万条
public function getopenid(){
$url ="https://api.weixin.qq.com/cgi-bin/user/get?access_token=".$this->access_token;
$result = $this->https_request($url);
$info = json_decode($result,true);
if(isset($info['data'])){
$users = $info['data']['openid'];
}else{
$users = null;
}
return $users;
}
//获取所有全部粉丝openid 一次最多拉取 1万条 需要多次拉取 next_openid=列表最后一个openid
public function getopenidall($nextid=null){
$next_openid = empty($nextid)?null:"&next_openid=".$nextid;
$url ="https://api.weixin.qq.com/cgi-bin/user/get?access_token=".$this->access_token.$next_openid;
$result = $this->https_request($url);
$info = json_decode($result,true);
if(isset($info['data'])){
$users = $info['data']['openid'];
$endid = $info['next_openid'];
}else{
$users = null;
$endid = null;
}
$openidArr = array(
'users'=>$users,
'endid'=>$endid
);
return $openidArr;
}
//创建底部菜单 注意菜单名称如果是数组转json 需要 urlencode() 汉字 打包后 在解码
public function wechatnav($arr){
$url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$this->access_token;
$jsondata = urldecode(json_encode($arr));
$ch = curl_init(); //创建一个请求
curl_setopt($ch,CURLOPT_URL,$url); //设置请求的url
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
curl_setopt($ch,CURLOPT_POST,1); //启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样
curl_setopt($ch,CURLOPT_POSTFIELDS,$jsondata); //全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
$output = curl_exec($ch); //执行请求
curl_close($ch); //关闭资源
return $output;
}
//查看底部菜单
public function getwechatnav(){
$url = "https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=".$this->access_token;
$data = $this->getHttp($url);
return $data;
}
public function deletenav(){ //删除底部菜单
return file_get_contents("https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=".$this->access_token);
}
//被动回复图文消息 注意:Xml里面不能有编辑器换行或者空格 严格要求官方数据格式
//只能关注回复才能使用高级素材模式 否则会自动转成客服消息图文模式
public function transmitNews($object,$newsArray){
if(!is_array($newsArray)){
return "";
}
$itemTpl = "-
";
$item_str = "";
foreach ($newsArray as $item){
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
}
$xmlTpl = "
%s
%s
$item_str
";
$result = sprintf($xmlTpl, $object['FromUserName'], $object['ToUserName'], time(), count($newsArray));
echo $result;
}
//被动回复文本消息 注意:Xml里面不能有编辑器换行或者空格 严格要求官方数据格式
public function transmitText($object,$content){
if (!isset($content) || empty($content)){
return "";
}
$xmlTpl = "
%s
";
$result = sprintf($xmlTpl, $object['FromUserName'], $object['ToUserName'], time(),'text',$content);
echo $result;
}
//关注回复发送图片
public function transmitImage($object,$mediaId){
if (!isset($mediaId) || empty($mediaId)){
return "";
}
$xmlTpl = "
%s
";
$result = sprintf($xmlTpl, $object['FromUserName'], $object['ToUserName'], time(),'image',$mediaId);
echo $result;
}
//推送模板消息
public function pushTemplate($openids=array(),$data=array()){
$touser = $openids;
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $this->access_token;
foreach ($touser as $value) {
$datapush = $this->getDataTemplateArray($value,$data);
$json_data = json_encode($datapush);//转化成json数组让微信可以接收
$res = $this->https_request($url, urldecode($json_data));//请求开始
$res = json_decode($res, true);
if ($res['errcode'] == 0 && $res['errcode'] == "ok"){
return 1;
}else{
return $res['errcode'];
}
}
}
//获取发送模板消息数据数组
public function getDataTemplateArray($openid,$data){
$data = array(
'touser' => $openid, //单个openid
'template_id' => $data['template'],
'url' => $data['link'],
'data' => array(
'first' => array(
'value' => $data['title'],
'color' => "#000"
),
'keyword1' => array(
'value' => $data['keyword1'],
'color' => $data['color2']
),
'keyword2' => array(
'value' => $data['keyword2'],
'color' => "#000"
),
'remark' => array(
'value' => $data['remark'],
'color' => $data['color3']
),
)
);
return $data;
}
public function getDataArrayKefu($value,$link){ //获取发送数据数组 发送文本客服消息
$data = array(
'touser' => $value, //要发送给用户的openid
'msgtype'=>'text',
'text' => array(
'content' =>$link
)
);
return $data;
}
public function getDataArrayKefuImg($value,$title,$description,$url,$imgurl){ //获取发送数据数组 发送图文客服消息
$data = '{
"touser":"'.$value.'",
"msgtype":"news",
"news":{
"articles": [
{
"title":"'.$title.'",
"description":"'.$description.'",
"url":"'.$url.'",
"picurl":"'.$imgurl.'"
}
]
}
}';
return $data;
}
//发送文本客服消息 text 需要urlencode编码一下
public function kefu($openids=array(),$text){
$touser = $openids;
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=". $this->access_token;
foreach ($touser as $value) {
$data = $this->getDataArrayKefu($value,$text);
$json_data = json_encode($data);//转化成json数组让微信可以接收
$res = $this->https_request($url, urldecode($json_data));//请求开始
$res = json_decode($res, true);
if ($res['errcode'] == 0 && $res['errcode'] == "ok"){
return '发送成功';
}else{
var_dump($res);
}
}
}
// 发送图文客服消息 openid 标题 描述 外链地址 图片地址
public function kefuImg($openids=array(),$title,$description,$linkurl,$imgurl){
$touser = $openids;
$url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=". $this->access_token;
foreach ($touser as $value) {
$data = $this->getDataArrayKefuImg($value,$title,$description,$linkurl,$imgurl);
$res = $this->https_request($url, $data);//请求开始
$res = json_decode($res, true);
if ($res['errcode'] == 0 && $res['errcode'] == "ok"){
return '发送成功';
}else{
var_dump($res);
}
}
}
//curl请求函数,微信都是通过该函数请求
public function https_request($url, $data = null){
$curl = curl_init(); //创建请求
curl_setopt($curl, CURLOPT_URL, $url); //设置请求的URL
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);//禁用后cURL将终止从服务端进行验证。使用CURLOPT_CAINFO选项设置证书使用CURLOPT_CAPATH选项设置证书目录 如果CURLOPT_SSL_VERIFYPEER(默认值为2)被启用,CURLOPT_SSL_VERIFYHOST需要被设置成TRUE否则设置为FALSE。
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);//1 检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。2 检查公用名是否存在,并且是否与提供的主机名匹配
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1); //设置为POST
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);//传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER,1);//在启用CURLOPT_RETURNTRANSFER的时候,返回原生的(Raw)输出。
$output = curl_exec($curl);//设置OK
curl_close($curl);
return $output;
}
// get请求
public function getHttp($url,$post_data=array()) {
$ch = curl_init($url);
$timeout = 6000;
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER,0 );
curl_setopt($ch, CURLOPT_FRESH_CONNECT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FORBID_REUSE, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data));
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
// 以下是高级群发 素材管理
// 上传图片 返回media_id
public function uploadImage($file,$type='image'){
$data = array('media' => new \CURLFile(realpath($file)));
$url = 'https://api.weixin.qq.com/cgi-bin/material/add_material?access_token='.$this->access_token.'&type='.$type;
$res = $this->https_request($url,$data);//请求开始
$res = json_decode($res, true);
if (isset($res['errcode'])){
return 0;
}else{
return $res['media_id'];
}
}
// 上传图文消息内的图片获取URL $file 必须服务器绝对路径
public function getimg($file){
$data = array('media' => new \CURLFile(realpath($file)));
$url = 'https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token='.$this->access_token;
$res = $this->https_request($url,$data);//请求开始
$res = json_decode($res, true);
if (isset($res['errcode'])){
return 0;
}else{
return $res['url'];
}
}
// 上传图文素材 返回素材的media_id
// 注意素材里的 文本需要 urlencode 编码 打包json后在 urldecode 数据才正确
// 编辑器里的文本需要 urlencode + htmlspecialchars(str_replace("\"", "'", $data['content'])) 然后 urldecode + htmlspecialchars_decode
// $data = 2维数组(必须)
public function upMaterial($data){
// $url = 'https://api.weixin.qq.com/cgi-bin/material/add_news?access_token='.$this->access_token;
$url = 'https://api.weixin.qq.com/cgi-bin/draft/add?access_token='.$this->access_token;
$news = array();
$news['articles'] = $data;
$news = json_encode($news);
$news = urldecode($news);
$news = htmlspecialchars_decode($news);
$res = $this->https_request($url,$news);//请求开始
$res = json_decode($res, true);
if (isset($res['errcode'])){
return null;
}else{
return $res['media_id'];
}
}
// 修改已经上传的图文素材 当个栏目修改
// 注意素材里的 文本需要 urlencode 编码 打包json后在 urldecode 数据才正确
// 编辑器里的文本需要 urlencode + htmlspecialchars(str_replace("\"", "'", $data['content'])) 然后 urldecode + htmlspecialchars_decode
// 正确时errcode的值应为0 $data = 一维数组 $media_id = 素材ID $index = 栏目所在素材位置
public function renewNews($data,$media_id,$index){
// $url = 'https://api.weixin.qq.com/cgi-bin/material/update_news?access_token='.$this->access_token;
$url = 'https://api.weixin.qq.com/cgi-bin/draft/update?access_token='.$this->access_token;
$news = array(
"media_id"=>$media_id,
"index"=>$index,
"articles"=>$data
);
$news = json_encode($news);
$news = urldecode($news);
$news = htmlspecialchars_decode($news);
$res = $this->https_request($url,urldecode($news));//请求开始
$res = json_decode($res, true);
if ($res['errcode']==0){
return 1;
}else{
return $res;
}
}
// 删除图文模板
public function delmd($media_id){
// $url = 'https://api.weixin.qq.com/cgi-bin/material/del_material?access_token='.$this->access_token;
$url = 'https://api.weixin.qq.com/cgi-bin/draft/delete?access_token='.$this->access_token;
$data = array('media_id'=>$media_id);
$data = json_encode($data);
$res = $this->https_request($url,$data);//请求开始
$res = json_decode($res, true);
if ($res['errcode']==0){
return 1;
}else{
return $res;
}
}
// 测试高级群发
public function ceshiPush($openid,$media_id){
$this->valid();
$this->getaccess_token();
$url = 'https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token='.$this->access_token;
$data = '{
"touser":"'.$openid.'",
"mpnews":{
"media_id":"'.$media_id.'"
},
"msgtype":"mpnews"
}';
$res = $this->https_request($url,$data);//请求开始
$res = json_decode($res, true);
if ($res['errcode']==0){
return '发送成功';
}else{
return $res['errmsg'];
}
}
// 开始高级群发 $openids = 一维数组 $media_id = 素材ID
public function advancedPush($openids,$media_id){
$url = 'https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token='.$this->access_token;
$openid = json_encode($openids);
$news = '{
"touser":'.$openid.',
"mpnews":{
"media_id":"'.$media_id.'"
},
"msgtype":"mpnews",
"send_ignore_reprint":1,
"is_to_all":"true"
}';
$res = $this->https_request($url,$news);//请求开始
$res = json_decode($res, true);
if ($res['errcode']==0){
return 1;
}else{
return $res['errmsg'];
}
}
}
?>