微信开发
微信开放平台:1725...
微信公众平台:w...2011(个人941471616871eb64dd35637e814c79f7)w...2010(服务)
小程序:a44...417838776(个人)
申请微信公众号测试号:方便我们做测试 不管你有木有微信直接扫码就行了
第一步:填写服务器配置 略过
第二步:验证消息的确来自微信服务器 略过
如果你一步在微信公众平台上填写正确填写url、EncodingAESKey和token时并点击提交 微信会向我们提交的域名所在的服务器发送get数据
提交时微信将下列书库发送到填写的url地址里如:
$nonce = $_GET['nonce']; $token = 'weixin'; $timestamp = $_GET['timestamp']; $echostr = $_GET['echostr']; $signature = $_GET['signature'];
上面几个参数组装比较, 成功原样返回echostr
$signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = 'weixin'; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ echo $_GET["echostr"]; }
验证比较通过后我们直接返回$echostr也可以不校验直接返回 提交的的表单就会将公众平台上的url和token、EncodingAESKey保存下来了;
token、EncodingAESKey这两个参数用于和url的access_token校验()
第三步:依据接口文档实现业务逻辑
微信请求都需要携带access_token
获取access_token https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=你的APPID&secret=你的APPSECRET
由于access_token有有效期我们可以采用文件保存的方式存放它 并且通过判断这个文件是否存在来确定它是否生成 通过判断文件的修改时间来判断是否过期
// 采用文件的方式存储token class Token { public static function get_file_token() { // 判断token文件是否存在 if (self::exists_token()) { // 如果token存在,判断是否过期 if (self::exprise_token()) { // token过期 //重新获取一次,$token,并且将文件删除,重新向文件里面写一次 $token = self::get_token(); unlink('token.txt'); file_put_contents('token.txt', $token); } else { // token 没有过期 $token = file_get_contents('token.txt'); } } else { // token文件不存在,则获取,并存入到token.txt $token = self::get_token(); file_put_contents('token.txt', $token);//(需要777权限) } // 返回token return $token; } //判断token.txt文件是否存在 private static function exists_token() { //判断token文件是否存在 if (file_exists('token.txt')) { return true; } else { return false; } } //判断文件是否过期:获取token.txt的创建时间,并且与当前执行index.php 文件的时间进行对比 private static function exprise_token() { //文件创建时间 $ctime = filectime('token.txt'); // 判断文件是否过期 if ((time() - $ctime) >= TIME) { // 过期 return true; } else { // 不过期 return false; } } // 获取token:通过CURL获取token private static function get_token() { // 1.初始化curl_init() $ch = curl_init(); // 2.获取token的微信服务器的URL地址 $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . APP_ID . '&secret=' . APP_SECRET; // 3.设置curl选项参数 curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//不加这个返回布尔值,加上则返回的就是服务器返回的结果 curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 4.执行一个cURL会话 $output = curl_exec($ch); // 5.关闭curl curl_close($ch); // 6.获取json数据 $obj = json_decode($output, true); // 7.返回access_token //成功返回{"access_token":"ACCESS_TOKEN","expires_in":7200} //失败返回{"errcode":40013,"errmsg":"invalid appid"} errcode可能包含的返回码-1 0 40001 40002 40163 return $obj['access_token']; } }
获取微信发送过来的内容
//$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //php7不再支持 $postStr = file_get_contents('php://input');
接受到的内容为xml格式 如下:
<xml><ToUserName><![CDATA[gh_3bba3aa9e2cb]]></ToUserName> <FromUserName><![CDATA[oW4qXv4qQLI1v5pjbmDGuG-qrcTE]]></FromUserName> <CreateTime>1536048244</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[呼呼]]></Content> <MsgId>6597276973499284306</MsgId> </xml>
注意:在xml中"< "、">"、"/"、""等是不被允许的如果xml中有这这些数据 那么必须转成<这种实体 而 ![CDATA[[ ]] 就避免了转化实体在它里面我们可以原样输出<这些特殊字符而不会报错
PHP将XML转换成数组/对象
simplexml_load_file($xmlstr,$class[,options,ns,is_prefix]) $class 为转成对象后的对象名
$xml= "<xml><name>tom</name></xml>";//XML文件 $objectxml = simplexml_load_string($xml);//将XML字符串转为对象curl获取的需要用到它 simplexml_load_file(filepath);//将xml文档转为对象 xml转数组需要自己写目前没有系统函数(吧?) $xmljson= json_encode($objectxml );//将对象转换个JSON $xmlarray=json_decode($xmljson,true);//将json转换成数组 默认是转对象
使用simplexml_load_string之前记得加上libxml_disable_entity_loader(true);//禁用加载外部实体的能力目的是防止XML注入攻击
不管是普通消息还是事件的xml都包含以下公共的属性
ToUserName 接受消息的一方
FromUserName 发送消息的一方
CreateTime 发送时间
MsgType 发送消息类型
MsgId 消息id
经过处理发送给用户的数据用xml组装然后echo组装好的xml就行了
注意注意!!!!!
<![CDATA[你好]]> xml中这段代码中的尖括号里面一定不要有空格换行啥的会报错啊!!!
小技巧
$xml= "<xml><appid>123456</appid></xml>";//XML文件 $objectxml = simplexml_load_string($xml);//将文件转换成 对象 $xmljson= json_encode($objectxml );//将对象转换个JSON $xmlarray=json_decode($xmljson,true);//将json转换成数组
/** * xml转数组或者转对象 * @param string $xmlstr xml格式的字符串 * @param boolean $isObj 为true则返回对象 * @return mixed 返回数组或者对象 */ function xmlStringToArr($xmlstr,$isObj=false){ libxml_disable_entity_loader(true); $objectxml = simplexml_load_string($xmlstr,'SimpleXMLElement',LIBXML_NOCDATA); if(boolval($isObj)){ return $objectxml; } return json_decode(json_encode($objectxml),true); } /** * 数组或者对象转xml * @param mixed $data 要转化的数组或者对象 * @return string 返回xml */ function arrayToXml($data){ $data=(array)$data; $xml = "<xml>"; foreach ($data as $key=>$val){ if(is_array($val)){ $xml.="<".$key.">".arrayToXml($val)."</".$key.">"; }else{ if(is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } } $xml.="</xml>"; return $xml; }
xml构造类
<?php class MessageComposition{ private $_messageObj=null; private $_domDocument=null; public function __construct($messageObj){ $this->_messageObj=$messageObj; $this->_domDocument = new DomDocument('1.0','utf-8'); $this->_init(); } private function _init(){ $dom = $this->_domDocument; $xml = $dom->createElement('xml');//创建普通节点:booklist $dom->appendChild($xml);//把xml节点加入到DOM文档中 $toUserName = $dom->createElement('ToUserName');//创建ToUserName节点 $xml->appendChild($toUserName);//把ToUserName节点加入到xml节点中 $toUserNameContent = $dom->createCDATASection($this->_messageObj->FromUserName);//创建文CDATA节点 $toUserName->appendChild($toUserNameContent);//把节点内容加入到ToUserName节点中 $fromUserName = $dom->createElement('FromUserName');//创建FromUserName节点 $xml->appendChild($fromUserName);//把FromUserName节点加入到xml节点中 $fromUserNameContent = $dom->createCDATASection($this->_messageObj->ToUserName);//创建文CDATA节点 $fromUserName->appendChild($fromUserNameContent);//把节点内容加入到FromUserName节点中 $createTime = $dom->createElement('CreateTime');//创建CreateTime节点 $xml->appendChild($createTime);//把CreateTime节点加入到xml节点中 $createTimeContent = $dom->createCDATASection(time());//创建文CDATA节点 $createTime->appendChild($createTimeContent);//把节点内容加入到CreateTime节点中 } /** *组装文本消息 * */ public function text($contents='默认回复消息'){ $dom=$this->_domDocument; $xml=$dom->documentElement; $xml_content = $dom->createElement('Content');//创建CreateTime节点 $xml->appendChild($xml_content);//把CreateTime节点加入到xml节点中 $xml_contentContent = $dom->createCDATASection($contents);//创建文CDATA节点 $xml_content->appendChild($xml_contentContent);//把节点内容加入到CreateTime节点中 $msgType = $dom->createElement('MsgType');//创建CreateTime节点 $xml->appendChild($msgType);//把CreateTime节点加入到xml节点中 $msgTypeNode = $dom->createCDATASection('text');//创建文CDATA节点 $msgType->appendChild($msgTypeNode );//把节点内容加入到CreateTime节点中 return $dom->savexml(); } /** *组装图文消息 * */ public function imageTtext($contents){ file_put_contents('./11112222.txt',print_r($contents,true).PHP_EOL,FILE_APPEND); $dom=$this->_domDocument; $xml=$dom->documentElement;//获取根节点 $msgType = $dom->createElement('MsgType');//创建CreateTime节点 $xml->appendChild($msgType);//把CreateTime节点加入到xml节点中 $msgTypeNode = $dom->createCDATASection('news');//创建文CDATA节点 $msgType->appendChild($msgTypeNode);//把节点内容加入到CreateTime节点中 $xml_ArticleCount=$dom->createElement('ArticleCount');//创建ArticleCount节点 $xml->appendChild($xml_ArticleCount);//把ArticleCount节点加入到xml节点中 $xml_ArticleCountNode = $dom->createCDATASection(count($contents));//创建文CDATA节点 $xml_ArticleCount->appendChild($xml_ArticleCountNode);//把节点内容加入到CreateTime节点中 $xml_Articles=$dom->createElement('Articles');//创建Articles节点 $xml->appendChild($xml_Articles);//把xml_Articles节点加入到xml节点中 foreach ($contents as $key => $value) { if($key>=7){ break; } $xml_Articles_item=$dom->createElement('item');//创建item节点 $xml_Articles->appendChild($xml_Articles_item);//把item节点加入到xml_Articles节点中 $xml_Articles_item_Title = $dom->createElement('Title');//创建Title节点 $xml_Articles_item->appendChild($xml_Articles_item_Title);//将Description节点加入到xml_Articles_item节点中 $xml_Articles_item_TitleNode = $dom->createCDATASection($value['Title']);//创建文CDATA节点 $xml_Articles_item_Title->appendChild($xml_Articles_item_TitleNode);//把节点内容加入到xml_Articles_item_Title节点中 $xml_Articles_item_Description = $dom->createElement('Description');//创建Description节点 $xml_Articles_item->appendChild($xml_Articles_item_Description);//将Description节点加入到xml_Articles_item节点中 $xml_Articles_item_DescriptionNode = $dom->createCDATASection($value['Description']);//创建文CDATA节点 $xml_Articles_item_Description->appendChild($xml_Articles_item_DescriptionNode);//把节点内容加入到item_Description节点中 $xml_Articles_item_PicUrl = $dom->createElement('PicUrl');//创建PicUrl节点 $xml_Articles_item->appendChild($xml_Articles_item_PicUrl);//将PicUrl节点加入到xml_Articles_item节点中 $xml_Articles_item_PicUrlNode = $dom->createCDATASection($value['PicUrl']);//创建文CDATA节点 $xml_Articles_item_PicUrl->appendChild($xml_Articles_item_PicUrlNode);//把节点内容加入到item_Description节点中 $xml_Articles_item_Url = $dom->createElement('Url');//创建Url节点 $xml_Articles_item->appendChild($xml_Articles_item_Url);//将Url节点加入到xml_Articles_item节点中 $xml_Articles_item_UrlNode = $dom->createCDATASection($value['Url']);//创建文CDATA节点 $xml_Articles_item_Url->appendChild($xml_Articles_item_UrlNode);//把节点内容加入到item_Description节点中 } return $dom->savexml(); } }
检测访问地址是否连接
/** * 检测访问地址是否连接得通 * @param string $url 远程url地址 * @return boolean 连通返回true,否则返回false */ function varify_url($url) { $check = @fopen($url,"r"); if($check) $status = true; else $status = false; return $status; }
上传临时素材和查看临时素材
上传:https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
获取:https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
例子:
$filepath = "D:/phpStudy/WWW/fastadmin/public/assets/img/qrcode.png"; $res=upload_media($filepath,'image');//上传临时素材 //var_dump($res); $url=get_download_media_url('STBU4zSakP77f7pw3OmzbE6t0eRxsVL5qvjvFtESUswW4varNLMp0RgHGNSpXm-I'); function upload_media($filepath,$sourcetype='image'){ if (class_exists ('\CURLFile')){ $filedata = array( 'fieldname' => new \CURLFile (realpath($filepath),'image/jpeg') ); } else { $filedata = array ( 'fieldname' => '@' . realpath($filepath) ); } $url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=" . get_access_token() . "&type=".$sourcetype; $res =upload ( $url, $filedata );//调用upload函数 return $res; } /** * 上传临时素材 * @param [type] $url [description] * @param [type] $filedata [description] * @return [type] [description] */ function upload($url, $filedata) { $curl = curl_init (); // CURLOPT_SAFE_UPLOAD 禁用@前缀 PHP 5.6.0 后必须开启 true (5.0是false) if (class_exists('CURLFile' )) {//php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默认值不同 curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } else { if (defined ( 'CURLOPT_SAFE_UPLOAD' )) { curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); }else{ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); if(version_compare(PHP_VERSION,'5.5.0', '>')){ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } } } curl_setopt ( $curl, CURLOPT_URL, $url );//设置请求的URL curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );//停止证书检查 curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE );//不对证书进行域名校对 if (! empty ( $filedata )) { curl_setopt ( $curl, CURLOPT_POST, 1 ); curl_setopt ( $curl, CURLOPT_POSTFIELDS, $filedata );//上传预备 } curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );//将获取的信息作为字符串返回而直接输出 //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //如果上传后有重定向 $output = curl_exec ( $curl ); curl_close ( $curl ); return $output; } function get_access_token(){ return '19__3YlI0gBfUOfPGtGYHireP-4F9BIHZR4I6WSKQfh08Q9upv7D-GoJYTEWvxpArX9tjc1CbW7JH7nf2NrWU04RSyrL_T0pJW9L00zgiUqBjOpLXxF56h9gMoBvQt6oHGIMDQaprQjsUz5bNh4HABeABADWX'; } /** * 获取临时素材 * @param [type] $media_id [description] * @return [type] [description] */ function get_download_media_url($media_id) { $url="https://api.weixin.qq.com/cgi-bin/media/get?access_token=".get_access_token()."&media_id=".$media_id; return $url; }
永久图文素材(单、多图文)
http请求方式: POST,https协议 https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
$filepath = "D:/phpStudy/WWW/fastadmin/public/assets/img/qrcode.png"; $data=[ 'articles'=>[ [ "title" =>"高铁晚点 损失谁偿", //"digest" =>"高铁旅客跟高铁运营方在购票时就形成了合同关系", "content"=>"文章内容体", "author" =>"思烁哥哥", "thumb_media_id"=> 'CKYeNC5thEGNvCGiRRMzk397NqDoEqJdNlDFfSCop_k', "content_source_url"=> "https://ai.bdstatic.com/file/0398624E1B0248FD9A91987D1C133BC0", 'show_cover_pic'=>true, 'need_open_comment'=>1,//可省略 Uint32 是否打开评论,0不打开,1打开 'only_fans_can_comment'=>0///可省略 Uint32 是否粉丝才可评论,0所有人可评论,1粉丝才可评论 ], [ "title" =>"文章标题 最多64个汉字", //"digest" =>"图文消息的摘要,仅有单图文消息才有摘要。多图文此处可传空。最多120个汉字",//可省略 "content"=>"文章内容体,最多20480个字符", "author" =>"作者 最多64个汉字",//可省略 "thumb_media_id"=> 'CKYeNC5thEGNvCGiRRMzk6mnP5MIdOFFZXI0ANjtLw0',//图文消息的封面图片素材id 整型 "content_source_url"=> "https://ai.bdstatic.com/file/0398624E1B0248FD9A91987D1C133BC0", 'show_cover_pic'=>true, 'need_open_comment'=>1,//可省略 Uint32 是否打开评论,0不打开,1打开 'only_fans_can_comment'=>0///可省略 Uint32 是否粉丝才可评论,0所有人可评论,1粉丝才可评论 ] ] ]; //$res=upload_articles_img($filepath); $res=upload_articles($data);//media_id:CKYeNC5thEGNvCGiRRMzk_hCf6AYTYAZao_E-MC3Dzk $edit_data=[ 'media_id'=>'media_id:CKYeNC5thEGNvCGiRRMzk_hCf6AYTYAZao_E-MC3Dzk', 'index'=>0, 'articles'=>[ [ "title" =>"高铁晚点 损失谁偿[修改]", //"digest" =>"高铁旅客跟高铁运营方在购票时就形成了合同关系", "content"=>"文章内容体", "author" =>"思烁哥哥", "thumb_media_id"=> 'CKYeNC5thEGNvCGiRRMzk397NqDoEqJdNlDFfSCop_k', "content_source_url"=> "http://baijiahao.baidu.com/s?id=1572607090874073", 'show_cover_pic'=>true, 'need_open_comment'=>1,//可省略 Uint32 是否打开评论,0不打开,1打开 'only_fans_can_comment'=>0///可省略 Uint32 是否粉丝才可评论,0所有人可评论,1粉丝才可评论 ], [ "title" =>"文章标题 最多64个汉字", //"digest" =>"图文消息的摘要,仅有单图文消息才有摘要。多图文此处可传空。最多120个汉字",//可省略 "content"=>"文章内容体,最多20480个字符", "author" =>"作者 最多64个汉字",//可省略 "thumb_media_id"=> 'CKYeNC5thEGNvCGiRRMzk6mnP5MIdOFFZXI0ANjtLw0',//图文消息的封面图片素材id 整型 "content_source_url"=> "http://baijiahao.baidu.com/s?id=1572607090874073", 'show_cover_pic'=>true, 'need_open_comment'=>1,//可省略 Uint32 是否打开评论,0不打开,1打开 'only_fans_can_comment'=>0///可省略 Uint32 是否粉丝才可评论,0所有人可评论,1粉丝才可评论 ] ] ]; $res=edit_forever_articles('CKYeNC5thEGNvCGiRRMzk_hCf6AYTYAZao_E-MC3Dzk',$edit_data,0); /** * 上传图文消息素材,用于群发(认证后的订阅号可用) 属于 news 类型 * @param array $data 消息结构{"articles":[{...}]} * @return boolean|array */ function upload_articles($data){ $url='https://api.weixin.qq.com/cgi-bin/material/add_news?access_token='.get_access_token(); $result = http_post($url,json_encode($data)); if ($result) { $json_result = json_decode($result,true); if (!$json_result || !empty($json_result['errcode'])) { $errCode = $json_result['errcode']; $errMsg = $json_result['errmsg']; return $errCode.': '.$errMsg; //return false; } return $json_result; } return false; } /** * 修改永久图文素材(认证后的订阅号可用) * 永久素材也可以在公众平台官网素材管理模块中看到 * @param string $media_id 图文素材id * @param array $data 消息结构{"articles":[{...}]} * @param int $index 更新的文章在图文素材的位置,第一篇为0,仅多图文使用 * @return boolean|array */ function edit_forever_articles($media_id,$data,$index=0){ if (!isset($data['media_id'])) $data['media_id'] = $media_id; if (!isset($data['index'])) $data['index'] = $index; $url='https://openapi.baidu.com/rest/2.0/cambrian/material/update_news?access_token='.get_access_token(); $result = http_post($url,json_encode($data)); if ($result) { $res = json_decode($result,true); if (!$res || !empty($res['errcode'])) { $errCode = $res['errcode']; $errMsg = $res['errmsg']; return $errcode.':'.$errMsg; //return false; } return $res; } return false; } /** * 上传临时素材 * @param [type] $url [description] * @param [type] $filedata [description] * @return [type] [description] */ function upload($url, $filedata) { $curl = curl_init (); // CURLOPT_SAFE_UPLOAD 禁用@前缀 PHP 5.6.0 后必须开启 true (5.0是false) if (class_exists('CURLFile' )) {//php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默认值不同 curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } else { if (defined ( 'CURLOPT_SAFE_UPLOAD' )) { curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); }else{ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); if(version_compare(PHP_VERSION,'5.5.0', '>')){ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } } } curl_setopt ( $curl, CURLOPT_URL, $url );//设置请求的URL curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );//停止证书检查 curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE );//不对证书进行域名校对 if (! empty ( $filedata )) { curl_setopt ( $curl, CURLOPT_POST, 1 ); curl_setopt ( $curl, CURLOPT_POSTFIELDS, $filedata );//上传预备 } curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );//将获取的信息作为字符串返回而直接输出 //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //如果上传后有重定向 $output = curl_exec ( $curl ); curl_close ( $curl ); return $output; } function get_access_token(){ return '19_MCMuAqt8ZjGzTHuf3TvExBc7L4B6_eNNeU3fDK-FgKLZGls4hcQqpVK6AYo4tL4irrgd5MUdRXILNvx9LJJj6q-9mNfOpP9wdj41MmHwENRW0iOcdWn-Ku7Ojt0LEYcACABUO'; } /** * POST 请求 * @param string $url * @param array $param * @param boolean $post_file 是否文件上传 * @return string content */ function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { $is_curlFile = true; } else { $is_curlFile = false; if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); } } if (is_string($param)) { $strPOST = $param; }elseif($post_file) { if($is_curlFile) { foreach ($param as $key => $val) { if (substr($val, 0, 1) == '@') { $param[$key] = new \CURLFile(realpath(substr($val,1))); } } } $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>$val){ $aPOST[] = $key."=".urlencode($val); } $strPOST = join("&", $aPOST); } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } }
上传图文消息内的图片获取URL
http请求方式: POST,https协议 https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
其他类型永久素材(image、voice、video、thumb)
http请求方式: POST,需使用https https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=TYPE
例子:
<?php $filepath = "D:/phpStudy/WWW/fastadmin/public/assets/img/qrcode.png"; //$res=upload_forever_media($filepath,'image');//上传 //var_dump($res); //media_id:CKYeNC5thEGNvCGiRRMzk6mnP5MIdOFFZXI0ANjtLw0 //url:http:\/\/mmbiz.qpic.cn\/mmbiz_png\/xxoo.png //获取永久素材 //$res=get_forever_media('CKYeNC5thEGNvCGiRRMzk6mnP5MIdOFFZXI0ANjtLw0',false); // 获取永久素材列表 $res=get_mediaList("image",0,20); var_dump($res);echo '<br>'; $res=get_mediaList_total(); var_dump($res);echo '<br>'; // 删除永久素材 $res=del_material('CKYeNC5thEGNvCGiRRMzkyCi-6_aRvvZPynPONSjxgM'); var_dump($res); // 上传永久素材 function upload_forever_media($filepath,$sourcetype='image'){ if (class_exists ('\CURLFile')){ $filedata = array( 'media' => new \CURLFile (realpath($filepath),'image/jpeg') ); } else { $filedata = array ( 'media' => '@' . realpath($filepath) ); } $url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=" . get_access_token() . "&type=".$sourcetype; $res =upload ($url, $filedata);//调用upload函数 return $res; } /** * 上传临时素材 * @param [type] $url [description] * @param [type] $filedata [description] * @return [type] [description] */ function upload($url, $filedata) { $curl = curl_init (); // CURLOPT_SAFE_UPLOAD 禁用@前缀 PHP 5.6.0 后必须开启 true (5.0是false) if (class_exists('CURLFile' )) {//php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默认值不同 curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } else { if (defined ( 'CURLOPT_SAFE_UPLOAD' )) { curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); }else{ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false ); if(version_compare(PHP_VERSION,'5.5.0', '>')){ curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true ); } } } curl_setopt ( $curl, CURLOPT_URL, $url );//设置请求的URL curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );//停止证书检查 curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE );//不对证书进行域名校对 if (! empty ( $filedata )) { curl_setopt ( $curl, CURLOPT_POST, 1 ); curl_setopt ( $curl, CURLOPT_POSTFIELDS, $filedata );//上传预备 } curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );//将获取的信息作为字符串返回而直接输出 //curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //如果上传后有重定向 $output = curl_exec ( $curl ); curl_close ( $curl ); return $output; } function get_access_token(){ return '19_beIjhcHa60OJxpjNn8W5al0CKOa1SDk5WPUUbZWy_bu-pNmrkW4LAGP0boxhhjBR-onVpqsneGqBEESfSF0oCf470FT1e11Mk9c0YW_yof_62LeuMAZ6M3IxH1QIPykyHUafZWBVP-KppeTTNKGbAHAGDZ'; } /** * 获取临时素材 * @param [type] $media_id [description] * @return [type] [description] */ function get_forever_media($media_id,$is_video=false) { $url="https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=".get_access_token(); $data=[ 'media_id'=>$media_id ]; //#TODO 暂不确定此接口是否需要让视频文件走http协议 //如果要获取的素材是视频文件时,不能使用https协议,必须更换成http协议 //$url_prefix = $is_video?str_replace('https','http',self::API_URL_PREFIX):self::API_URL_PREFIX; $res=http_post($url,json_encode($data)); //将获取到的文件流保存到指定的目录 if($res){ file_put_contents(iconv('utf-8', 'gbk', __DIR__ . DIRECTORY_SEPARATOR.'img'.DIRECTORY_SEPARATOR.time().uniqid() . '.png'), $res); } return $res; } /** * url方式请求 * * @param string $url 要请求的url地址 * @param array $data 要发送的数据 存在该参数就启用post提交,否则为get请求 * @return mixed $output 返回请求的结果 */ function curl($url, $data = null){ // 1.创建一个新的CURL资源 $ch = curl_init(); // 2.设置URL相应的选项 curl_setopt($ch, CURLOPT_URL, $url); // 设置请求的URL地址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出(0为直接输出) //curl_setopt($ch, CURLOPT_HEADER, 0); // 启用时会将头文件的信息作为数据流输出 curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置cURL允许执行的最长秒数 curl_setopt($ch, CURLOPT_POST, $data ? 1 : 0); // 存在data就启用post发送 启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // //忽略证书 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 3.抓去URL并将它传递给浏览器 $output = curl_exec($ch); // 4.关闭CURL资源,并且释放系统资源 curl_close($ch); // 返回输出 return $output; } /** * 获取素材列表 */ function get_mediaList($type="image",$offset=0,$count=20){ $data = array( 'type'=>$type, 'offset'=>$offset, 'count'=>$count ); $url = 'https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token='.get_access_token(); $result=curl($url,json_encode($data)); return $result; } /** * 获取素材总数 */ function get_mediaList_total(){ $url = 'https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token='.get_access_token(); $result=curl($url); return $result; } //删除永久素材 function del_material($media_id){ $url = 'https://api.weixin.qq.com/cgi-bin/material/del_material?access_token='.get_access_token(); $data= array('media_id'=>$media_id); $result=curl($url,json_encode($data)); return $result; } /** * POST 请求 * @param string $url * @param array $param * @param boolean $post_file 是否文件上传 * @return string content */ function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { $is_curlFile = true; } else { $is_curlFile = false; if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); } } if (is_string($param)) { $strPOST = $param; }elseif($post_file) { if($is_curlFile) { foreach ($param as $key => $val) { if (substr($val, 0, 1) == '@') { $param[$key] = new \CURLFile(realpath(substr($val,1))); } } } $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>$val){ $aPOST[] = $key."=".urlencode($val); } $strPOST = join("&", $aPOST); } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } }
用户管理(image、voice、video、thumb)
设置用户备注名
https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token=ACCESS_TOKEN post请求 格式;json { "openid":"oDF3iY9ffA-hqb2vVvbr7qxf6A0Q",//用户标识 "remark":"pangzi" //新的备注名 }
<?php function get_access_token(){ return '19_ZE8Pax9ZYFrGako9irbSlpegUMjGwuZXj3BEJNZ7XzZ224I0qsc-Nzkd1nVGKbHvb8tAZZENeQCEJgJAyIkBN_CE6NJZsu2vEnOdnATpmGT-CqzdII9tAqGf4dzjoTW5tvMPHWB6CsUpioVgJQMbAJAOVR'; } /** * POST 请求 * @param string $url * @param array $param * @param boolean $post_file 是否文件上传 * @return string content */ function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { $is_curlFile = true; } else { $is_curlFile = false; if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); } } if (is_string($param)) { $strPOST = $param; }elseif($post_file) { if($is_curlFile) { foreach ($param as $key => $val) { if (substr($val, 0, 1) == '@') { $param[$key] = new \CURLFile(realpath(substr($val,1))); } } } $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>$val){ $aPOST[] = $key."=".urlencode($val); } $strPOST = join("&", $aPOST); } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } } /** * url get或者post方式请求 * * @param string $url 要请求的url地址 * @param array $data 要发送的数据 存在该参数就启用post提交,否则为get请求 * @return mixed $output 返回请求的结果 */ function curl($url, $data = null){ // 1.创建一个新的CURL资源 $ch = curl_init(); // 2.设置URL相应的选项 curl_setopt($ch, CURLOPT_URL, $url); // 设置请求的URL地址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出(0为直接输出) //curl_setopt($ch, CURLOPT_HEADER, 0); // 启用时会将头文件的信息作为数据流输出 curl_setopt($ch, CURLOPT_TIMEOUT, 10); // 设置cURL允许执行的最长秒数 curl_setopt($ch, CURLOPT_POST, $data ? 1 : 0); // 存在data就启用post发送 启用时会发送一个常规的POST请求,类型为:application/x-www-form-urlencoded,就像表单提交的一样。 curl_setopt($ch, CURLOPT_POSTFIELDS, $data); //data必须数组 //忽略证书 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 3.抓去URL并将它传递给浏览器 $output = curl_exec($ch); // 4.关闭CURL资源,并且释放系统资源 curl_close($ch); // 返回输出 return $output; } /** * 创建用户标签 * @param array $data 请求创建标签的构造数组 * @return json errcode and errmsg 成功返回id(100) name(标签名) */ function create_user_tag($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/create?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } $data=[ 'tag'=>[ 'name'=>'标签名', ] ]; /** * 获取已创建的用户标签 * {"tags":[{"id":2,"name":"星标组","count":0},{"id":100,"name":"\\u6807\\u7b7e\\u540d","count":0}]} * @return json 成功返回id(100) name(标签名) */ function get_user_tag(){ $url='https://api.weixin.qq.com/cgi-bin/tags/get?access_token='.get_access_token(); $res=curl($url,null); var_dump($res); } /** * 修改用户标签 * $data=['tag'=>['id'=>100,'name'=>'修改名']] * @param array $data 修改标签的构造包含id和name的数组 * @return json {"errcode":0,"errmsg":"ok"} */ function edit_user_tag($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/update?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 删除用户标签 * $data=['tag'=>['id'=>100]] * @param array $data 删除标签的构造包含id的数组 * @return json {"errcode":0,"errmsg":"ok"} */ function delete_user_tag($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/delete?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 批量为用户打标签 * $data=['tagid'=>100,'openid_list'=>['经过处理的微信号','xxx','...']] * @param array $data * @return json {"errcode":0,"errmsg":"ok"} */ function batch_user_tag($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 批量删除给用户打的标签 * $data=['tagid'=>100,'openid_list'=>['经过处理的微信号','xxx','...']] * @param array $data * @return json {"errcode":0,"errmsg":"ok"} */ function batch_user_untag($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 获取用户的标签 * $data=['openid'=>'ocYxcuBt0mRugKZ7tGAHPnUaOW7Y'] * @param array $data 包含iopenid的数组 * @return json {"tagid_list":[134,100]} */ function get_user_tags($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 设置用户备注名 * $data=['openid'=>'ocYxcuBt0mRugKZ7tGAHPnUaOW7Y','remark'=>'老板'] * @param array $data 包含iopenid的数组 * @return json {"errcode":0,"errmsg":"ok"} */ function set_user_remark($data){ $url='https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 获取用户基本信息(UnionID机制) get * openid 是经过处理的用户微信号 * @return json {"errcode":40013,"errmsg":"invalid appid"} */ function get_user_info(){ $url='https://api.weixin.qq.com/cgi-bin/user/info?access_token='.get_access_token().'&openid='.'oW4qXv0YWsduTcCwkaqhXtsHdvSQ'.'&lang=zh_CN'; $res=curl($url); var_dump($res); } /** * 批量获取用户基本信息(UnionID机制) post * $data=['user_list'=>[['openid'=>'ocYxcuBt0mRugKZ7tGAHPnUaOW7Y','lang'=>'zh_CN']],[...],[...]] * @param array $data 包含iopenid的数组 * @return json {"errcode":40013,"errmsg":"invalid appid"} */ function get_users_info($data){ $url='https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 获取用户列表 * openid 是经过j加密处理的用户微信号 * @param string $next_openid 设置它就会从设置的这个openid开始拉取 * @return json */ function get_userlist($next_openid=''){ if(!empty($next_openid)&&is_string($next_openid)){ $url_prefix='&next_openid='.$next_openid; }else{ $url_prefix=''; } $url='https://api.weixin.qq.com/cgi-bin/user/get?access_token='.get_access_token().$url_prefix; $res=curl($url); var_dump($res); } /** * 获取公众号的黑名单列表 post * $data=[openid'=>'ocYxcuBt0mRugKZ7tGAHPnUaOW7Y'] * @param array $data 包含从此openid用户开始拉取的数组,为空则从头拉取 @return json {"errcode":40013,"errmsg":"invalid appid"} */ function get_users_blacklist($data=[]){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/getblacklist?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 拉黑用户们 post * $data=[openid_list'=>['ocYxcuBt0mRugKZ7tGAHPnUaOW7Y',ocYxcuBt0mRugKZ7tGAHPnUaOW8Y,...]] * @param array $data 包含从此openid用户开始拉取的数组 @return json {"errcode":40013,"errmsg":"invalid appid"} */ function black_users($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchblacklist?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); } /** * 取消拉黑用户们 post * $data=[openid_list'=>['ocYxcuBt0mRugKZ7tGAHPnUaOW7Y',ocYxcuBt0mRugKZ7tGAHPnUaOW8Y,...]] * @param array $data 包含从此openid用户开始拉取的数组 @return json {"errcode":40013,"errmsg":"invalid appid"} */ function black_users($data){ $url='https://api.weixin.qq.com/cgi-bin/tags/members/batchunblacklist?access_token='.get_access_token(); $res=http_post($url,json_encode($data)); var_dump($res); }
生成带参数的二维码
<?php function get_access_token(){ return '19_qM098D7wAtGEzCkNHifyIosUUtzh-TL-U3djbNVMOOphQjeeFWZ0EsEHNL7Npk245jl50oEjGDoN5RZnORSpwqM_R1JirpmSbRM8Rx_N19zPunHqIVPzdT-yoxjCycmXLNJDeyaJriNw6B6SCAXfAHATRO'; } /** * POST 请求 * @param string $url * @param array $param * @param boolean $post_file 是否文件上传 * @return string content */ function http_post($url,$param,$post_file=false){ $oCurl = curl_init(); if(stripos($url,"https://")!==FALSE){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { $is_curlFile = true; } else { $is_curlFile = false; if (defined('CURLOPT_SAFE_UPLOAD')) { curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); } } if (is_string($param)) { $strPOST = $param; }elseif($post_file) { if($is_curlFile) { foreach ($param as $key => $val) { if (substr($val, 0, 1) == '@') { $param[$key] = new \CURLFile(realpath(substr($val,1))); } } } $strPOST = $param; } else { $aPOST = array(); foreach($param as $key=>$val){ $aPOST[] = $key."=".urlencode($val); } $strPOST = join("&", $aPOST); } curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); if(intval($aStatus["http_code"])==200){ return $sContent; }else{ return false; } } /** * 生成临时二维码 默认临时字符串场景二维码 * $data=['expire_seconds'=>604800,'action_name'=>'QR_SCENE','action_info'=>['scene'=>['scene_id'=>123]]]; * or $data=[ 'expire_seconds'=>604800,//该二维码有效时间(S) 永久不要该参数 'action_name'=>'QR_STR_SCENE',//二维码类型QR_SCENE,QR_STR_SCENE为临时,QR_LIMIT_SCENE,QR_LIMIT_STR_SCENE为永久 'action_info'=>[ 'scene'=>[ 'scene_str'=>'test' ] ] ]; * @param array $data * @param array $data * @param array $data * @param array $data * @return json * */ function create_qrcode($scene_value,$time=604800,$data=[],$is_int_scene=null) { $url='https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.get_access_token(); if(empty($data)){ if($is_int_scene===null||!is_bool($is_int_scene)){ if(preg_match('/^(?!0)(?:[0-9]{1,5}|100000)$/', $scene_value)){ $action_info=['action_info'=>['scene'=>['scene_id'=>$scene_value]]]; }else{ $action_info=['action_info'=>['scene'=>['scene_str'=>strval($scene_value)]]]; $scene_value=strval($scene_value); } } if($is_int_scene===true){ $action_info=['action_info'=>['scene'=>['scene_id'=>$scene_value]]]; }else if($is_int_scene===false){ $action_info=['action_info'=>['scene'=>['scene_str'=>strval($scene_value)]]]; } //var_dump($scene); if($time==0){ //time=0表示永久二维码 $expire_seconds=[]; if(array_key_exists('scene_id', $action_info['action_info']['scene'])){ $action_name =['action_name'=>'QR_LIMIT_SCENE']; }else{ $action_name =['action_name'=>'QR_LIMIT_STR_SCENE']; } }else{ $expire_seconds=['expire_seconds'=>$time]; if(array_key_exists('scene_id', $action_info['action_info']['scene'])){ $action_name =['action_name'=>'QR_SCENE']; }else{ $action_name =['action_name'=>'QR_STR_SCENE']; } } $data=array_merge($expire_seconds,$action_name,$action_info); } $res=http_post($url,json_encode($data)); var_dump($res); } //create_qrcode('test'); /** * 通过ticket换取二维码的url */ function get_qrcode_by_ticket($ticket){ $url='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket='.urlencode($ticket); return $url; } $ticket='gQEp8TwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyNkNnYUIwcmFhbl8xQjBEZWhzYzIAAgTALIVcAwSAOgkA'; $res=get_qrcode_by_ticket($ticket); echo $res;
长链接转短链接接口
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
生成带参数的二维码
echostr