准备工具:
微信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("接受:\n".$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."\n",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("接受:\n".$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("发送图文消息:\n".$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."\n",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:\israel\upload\winter.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);
?>