准备工具:
微信web开发工具
微信术语解释:
access_token 就是一个签名,用来验证图片或者文件是否是从自己的公众账户发出去的
微信出现的奇葩问题:
1,将配置信息填好后,微信不出现任何的问题 解决:服务器配置选项没有打开
2, 大小写,图片要注意是否是多图文还是单图文,单图文,数量要写成1
最近在学习微信开发,遇到的问题记录在这里
1,微信js sdk invalid signature签名错误 问题解决。
https://my.oschina.net/u/2308739/blog/371414/
2,使用的是新浪云,豆豆的那种,如果没有经过个人信息检验,是无法通过token验证的
3,使用到的函数
simplexml_load_string();
<?php $xml = <<<xml <?xml version='1.0' encoding = 'utf-8' ?> <!-- 定义xml的代码,不定义可能会产生乱码 -->
<ToUserName>
<![CDATA[toUser]]>
</ToUserName>
</xml>
xml;
$obj = simplexml_load_string($xml->ToUserName); ?> <!-- 将上面的xml转化为php对象格式-->
3,接口介绍
1,json格式 {"id":"1","username":"u76ca"} 2,xml格式
$xml = <<<xml <?xml version='1.0' encoding = 'utf-8' ?> <!-- 定义xml的代码,不定义可能会产生乱码 -->
<!-- 将微信端的demo复制到里面 --> <ToUserName> <![CDATA[toUser]]> </ToUserName> </xml> xml;
4,将array转化为json数据
<?php $array = array('id'=>'1','userName'=>'yida'); $arr = json_encode($array); //将数组转化为json数据
$obj = json_decode($arr); //将json转化为对象 $obj->属性 var_dump($arr); ?>
5,微信验证匹配 -- 微信端 和 服务器端进行验证
1,将微信端填入 url 和 token 信息
2,当写好后会将token信息发送到url地址上面去
3,在服务器端写入token 信息,匹配成功可以进行操作
4,微信一般验证一次,就不需要再次验证了
<?php if(!isset($_GET['echostr'])){ $obj->receive(); }else{ $obj->checkSignature(); } class Weixin{ public function checkSignature() { //向服务器校验token } public function receive(){ } } ?>
1,自动回复
<?php define('TOKEN','weixin'); $obj=new Weixin(); if(!isset($_GET['echostr'])){ $obj->receive(); }else{ $obj->checkSignature(); } class Weixin{ public function checkSignature() { $signature = $_GET["signature"]; //加密签名 $timestamp = $_GET["timestamp"]; //时间戳 $nonce = $_GET["nonce"]; //随机数 $token = TOKEN; //token $tmpArr = array($token, $timestamp, $nonce);//组成新数组 sort($tmpArr, SORT_STRING);//重新排序 $tmpStr = implode( $tmpArr );//转换成字符串 $tmpStr = sha1( $tmpStr ); //再将字符串进行加密 if( $tmpStr == $signature ){ echo $_GET['echostr']; }else{ return false; } } public function receive(){ $obj=$GLOBALS['HTTP_RAW_POST_DATA']; $postSql=simplexml_load_string($obj,'SimpleXMLElement',LIBXML_NOCDATA); $this->logger("接受: ".$obj); if(!empty($postSql)){ switch(trim($postSql->MsgType)){ case "text" : $result=$this->receiveText($postSql); if(!empty($result)){ echo $result; }else{ $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; echo $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),$postSql->MsgType,"没有这条文本消息"); } } } } private function receiveText($postSql){ $content=trim($postSql->Content); if(strstr($content,"你好")){ $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),$postSql->MsgType,"hello"); return $result; } } private function logger($content){ $logSize=100000; $log="log.txt"; if(file_exists($log) && filesize($log) > $logSize){ unlink($log); } file_put_contents($log,date('H:i:s')." ".$content." ",FILE_APPEND); } } ?>
5,多图文
<?php define('TOKEN','weixin'); $obj=new Weixin(); if(!isset($_GET['echostr'])){ $obj->receive(); }else{ $obj->checkSignature(); } class Weixin{ public function checkSignature() { $signature = $_GET["signature"]; //加密签名 $timestamp = $_GET["timestamp"]; //时间戳 $nonce = $_GET["nonce"]; //随机数 $token = TOKEN; //token $tmpArr = array($token, $timestamp, $nonce);//组成新数组 sort($tmpArr, SORT_STRING);//重新排序 $tmpStr = implode( $tmpArr );//转换成字符串 $tmpStr = sha1( $tmpStr ); //再将字符串进行加密 if( $tmpStr == $signature ){ echo $_GET['echostr']; }else{ return false; } } public function receive(){ $obj=$GLOBALS['HTTP_RAW_POST_DATA']; $postSql=simplexml_load_string($obj,'SimpleXMLElement',LIBXML_NOCDATA); $this->logger("接受: ".$obj); if(!empty($postSql)){ switch(trim($postSql->MsgType)){ case "text" : $result=$this->receiveText($postSql); if(!empty($result)){ echo $result; }else{ $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; echo $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),$postSql->MsgType,"没有这条文本消息"); } } } } private function receiveText($postSql){ $content=trim($postSql->Content); if(strstr($content,"你好")){ $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),$postSql->MsgType,"hello"); }else if(strstr($content,"单图文")){ $result=$this->receiveImage($postSql); }else if(strstr($content,"多图文")){ $result=$this->receiveImages($postSql); } $this->logger("发送图文消息: ".$result); return $result; } private function receiveImage($postSql){ $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <ArticleCount>1</ArticleCount> <Articles> <item> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item> </Articles> </xml> "; $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),"news","跟益达学微信开发,教益达泡妹子","它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); return $result; } private function receiveImages($postSql){ $content=array(); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $content[]=array("Title"=>"跟益达学微信开发,教益达泡妹子","Description"=>"它就是 中国海南海花岛——缤纷水上乐园 23项游乐 打造雪山滑道区、激流河道区 巨浪演绎区、阖家欢乐区 极限滑道区五大主题游乐区","PicUrl"=>"http://pic14.nipic.com/20110522/7411759_164157418126_2.jpg","http://www.maiziedu.com/"); $str="<item> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <PicUrl><![CDATA[%s]]></PicUrl> <Url><![CDATA[%s]]></Url> </item>"; $news=""; foreach ($content as $newArray) { $news.=sprintf($str,$newArray['Title'],$newArray['Description'],$newArray['PicUrl'],$newArray['Url']); } $xml="<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <ArticleCount>%s</ArticleCount> <Articles> $news </Articles> </xml> "; $result=sprintf($xml,$postSql->FromUserName,$postSql->ToUserName,time(),"news",count($content)); return $result; } private function logger($content){ $logSize=100000; $log="log.txt"; if(file_exists($log) && filesize($log) > $logSize){ unlink($log); } file_put_contents($log,date('H:i:s')." ".$content." ",FILE_APPEND); } } ?>
10,使用到的函数总结
1)$GLOBALS['HTTP_RAW_POST_DATA'] 服务器接收来自微信发送的XML文件
This is useful in cases where the post Content-Type is not something PHP understands (such as text/xml).
也就是说,基本上$GLOBALS['HTTP_RAW_POST_DATA'] 和 $_POST是一样的。但是如果post过来的数据不是PHP能够识别的,你可以用 $GLOBALS['HTTP_RAW_POST_DATA']来接收,比如 text/xml 或者 soap 等等。
PHP默认识别的数据类型是application/x-www.form-urlencoded标准的数据类型
用Content-Type=text/xml 类型,提交一个xml文档内容给了php server,要怎么获得这个POST数据。
The RAW / uninterpreted HTTP POST information can be accessed with: $GLOBALS['HTTP_RAW_POST_DATA'] This is useful in cases where the post Content-Type is not something PHP understands (such as text/xml).
由于PHP默认只识别application/x-www.form-urlencoded标准的数据类型,因此,对型如text/xml的内容无法解析为$_POST数组,故保留原型,交给$GLOBALS['HTTP_RAW_POST_DATA'] 来接收。
另外还有一项 php://input 也可以实现此这个功能
php://input 允许读取 POST 的原始数据。和 $HTTP_RAW_POST_DATA 比起来,它给内存带来的压力较小,并且不需要任何特殊的 php.ini 设置。php://input 不能用于 enctype="multipart/form-data"。
11,微信发送媒体文件注意项:
微信公众账号在回复图片、语音、视频的时候,将使用media_id来调用相关文件。
一、上传多媒体文件
公众号可调用本接口来上传图片、语音、视频等文件到微信服务器,上传后服务器会返回对应的media_id,公众号此后可根据该media_id来获取多媒体。请注意,media_id是可复用的,调用该接口需http协议。
通常,文件上传是通过html表单进行的,但通过CURL可以不经过浏览器,直接在服务器端进行表单的POST提交,完成文件上传功能。
需要注意的是:文件名必须是完整绝对路径,另外需要绝对路径前加上“@”以示区分。
在Windows服务器上,格式示例为:”@F:israeluploadwinter.jpg”,而在Linux服务器上,格式示例为:”@home/israel/upload/winter.jpg”。
http请求方式: POST/FORM
http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
参数说明
返回结果
{
"type": "thumb",
"thumb_media_id": "2RhP0caRKHVOmZO5AKelHkK--vqPPwgUaRp5-WE63dvmmPRWiYVKgvNblIp_gv79",
"created_at": 1389794771
}
案例分析:
<?php function http_curl($url,$data=null){ //1.初始化,创建一个新cURL资源 $ch = curl_init(); //2.设置URL和相应的选项 curl_setopt($ch, CURLOPT_URL, $url); //curl_setopt($ch, CURLOPT_HEADER, 0); if(!empty($data)){ curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); } curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//禁止curl资源直接输出 //3.抓取URL并把它传递给浏览器 $opt=curl_exec($ch); //4.关闭cURL资源,并且释放系统资源 curl_close($ch); return $opt; } function get_token(){ $appid="wx9e583a9d8dacbec8"; $secret="aa2794a1a3c555740542d52d397a7dfd"; $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}"; $json=http_curl($url); $result=json_decode($json); return $result->access_token; } $token=get_token(); $type="image"; $path=dirname(__FILE__)."/xiaotu.jpg"; $data=array("media"=>"@".$path); $url="http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$token}&type={$type}"; $arr=http_curl($url,$data); var_dump($arr); ?>