PHP对接微信公众平台消息接口开发流程教程


Posted in PHP onMarch 25, 2014

一、写好接口程序

在你的服务器上上传好一个接口程序文件,如http://www.yourdomain.com/weixin.php  内容如下:

<?php
define("TOKEN", "weixin");//自己定义的token 就是个通信的私钥
$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();
//$wechatObj->responseMsg();
class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }
    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $fromUsername = $postObj->FromUserName;
            $toUsername = $postObj->ToUserName;
            $keyword = trim($postObj->Content);
            $time = time();
            $textTpl = "<xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[%s]]></MsgType>
            <Content><![CDATA[%s]]></Content>
            <FuncFlag>0<FuncFlag>
            </xml>";
            if(!empty( $keyword ))
            {
                $msgType = "text";
                $contentStr = '你好啊,?潘?;
                $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                echo $resultStr;
            }else{
                echo '咋不说哈呢';
            }
        }else {
            echo '咋不说哈呢';
            exit;
        }
    }    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
        $token =TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );
        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
}
?>

二、配置微信公众平台回复接口

设置回复接口,填好URL和Token(url填上面的http://www.yourdomain.com/weixin.php,token必须跟上面程序里面定义的Token一致)

PHP对接微信公众平台消息接口开发流程教程

三、验证接口

用自己的个人微信关注下你的公众账号,给这个账号发一条消息过去,收到原样的消息返回,即验证成功了。

四、开始自定义回复

注释掉$wechatObj->valid(); 这行,同时去掉//$wechatObj->responseMsg();这行的注释。
你可以修改responseMsg函数里面的代码,根据用户的消息类型('text','image','location')和消息内容来回复用户不同的内容。
消息接口就可以使用了,发个消息试试看吧?

1.封装weixin.class.php

由于微信公众平台的通信使用的是特定格式的XML数据,每次接受和回复都要去做一大堆的数据处理。
我们就考虑在这个基础上做一次封装,weixin.class.php,代码如下:

<?php
class Weixin
{
    public $token = '';//token
    public $debug =  false;//是否debug的状态标示,方便我们在调试的时候记录一些中间数据
    public $setFlag = false;
    public $msgtype = 'text';   //('text','image','location')
    public $msg = array();    public function __construct($token,$debug)
    {
        $this->token = $token;
        $this->debug = $debug;
    }
    //获得用户发过来的消息(消息内容和消息类型  )
    public function getMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if ($this->debug) {
                        $this->write_log($postStr);
        }
        if (!empty($postStr)) {
            $this->msg = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $this->msgtype = strtolower($this->msg['MsgType']);
        }
    }

//回复文本消息
    public function makeText($text='')
    {
        $CreateTime = time();
        $FuncFlag = $this->setFlag ? 1 : 0;
        $textTpl = "<xml>
            <ToUserName><![CDATA[{$this->msg['FromUserName']}]]></ToUserName>
            <FromUserName><![CDATA[{$this->msg['ToUserName']}]]></FromUserName>
            <CreateTime>{$CreateTime}</CreateTime>
            <MsgType><![CDATA
            1  
            ]></MsgType>
            <Content><![CDATA[%s]]></Content>
            <FuncFlag>%s</FuncFlag>
            </xml>";
        return sprintf($textTpl,$text,$FuncFlag);
    }
    //根据数组参数回复图文消息
    public function makeNews($newsData=array())
    {
        $CreateTime = time();
        $FuncFlag = $this->setFlag ? 1 : 0;
        $newTplHeader = "<xml>
            <ToUserName><![CDATA[{$this->msg['FromUserName']}]]></ToUserName>
            <FromUserName><![CDATA[{$this->msg['ToUserName']}]]></FromUserName>
            <CreateTime>{$CreateTime}</CreateTime>
            <MsgType><![CDATA[news]]></MsgType>
            <Content><![CDATA[%s]]></Content>
            <ArticleCount>%s</ArticleCount><Articles>";
        $newTplItem = "<item>
            <Title><![CDATA[%s]]></Title>
            <Description><![CDATA[%s]]></Description>
            <PicUrl><![CDATA[%s]]></PicUrl>
            <Url><![CDATA[%s]]></Url>
            </item>";
        $newTplFoot = "</Articles>
            <FuncFlag>%s</FuncFlag>
            </xml>";
        $Content = '';
        $itemsCount = count($newsData['items']);
        $itemsCount = $itemsCount < 10 ? $itemsCount : 10;//微信公众平台图文回复的消息一次最多10条
        if ($itemsCount) {
            foreach ($newsData['items'] as $key => $item) {
                if ($key<=9) {
                    $Content .= sprintf($newTplItem,$item['title'],$item['description'],$item['picurl'],$item['url']);
                }
            }
        }
        $header = sprintf($newTplHeader,$newsData['content'],$itemsCount);
        $footer = sprintf($newTplFoot,$FuncFlag);
        return $header . $Content . $footer;
    }
    public function reply($data)
    {
        if ($this->debug) {
                    $this->write_log($data);
        }
        echo $data;
    }
    public function valid()
    {
        if ($this->checkSignature()) {
            if( $_SERVER['REQUEST_METHOD']=='GET' )
            {
                echo $_GET['echostr'];
                exit;
            }
        }else{
            write_log('认证失败');
            exit;
        }
    }
    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
        $tmpArr = array($this->token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );
        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
    private function write_log($log){
        //这里是你记录调试信息的地方  请自行完善   以便中间调试
    }
}
?>

2.调用weixin.class.php

把你的微信公众平台主接口文件(如前面定义的http://www.yourdomain.com/weixin.php)中,修改代码为:

<?php
include_once('weixin.class.php');//引用刚定义的微信消息处理类
define("TOKEN", "mmhelper");
define('DEBUG', true);
$weixin = new Weixin(TOKEN,DEBUG);//实例化
$weixin->getMsg();
$type = $weixin->msgtype;//消息类型
$username = $weixin->msg['FromUserName'];//哪个用户给你发的消息,这个$username是微信加密之后的,但是每个用户都是一一对应的
if ($type==='text') {
    if ($weixin->msg['Content']=='Hello2BizUser') {//微信用户第一次关注你的账号的时候,你的公众账号就会受到一条内容为'Hello2BizUser'的消息
        $reply = $weixin->makeText('欢迎你关注哦,?潘?);
    }else{//这里就是用户输入了文本信息
        $keyword = $weixin->msg['Content'];   //用户的文本消息内容
                include_once("chaxun.php");//文本消息 调用查询程序 
                $chaxun= new chaxun(DEBUG,$keyword,$username);
                $results['items'] =$chaxun->search();//查询的代码                $reply = $weixin->makeNews($results);
    }
}elseif ($type==='location') {
      //用户发送的是位置信息  稍后的文章中会处理                 
}elseif ($type==='image') {
      //用户发送的是图片 稍后的文章中会处理
}elseif ($type==='voice') {    
      //用户发送的是声音 稍后的文章中会处理
}
$weixin->reply($reply);
?>

3.查询代码

还需要将数据库里面的查询结果格式化为特定的形式

<?php
public function search(){
       $record=array();  //定义返回结果的数组
       $list = $this->search($this->keyword);//普通的根据关键词查询数据库的操作  代码就不用分享了

if(is_array($list)&&!empty($list)){                
               foreach($list as $msg){
    



$record[]=array(//以下代码,将数据库中查询返回的数组格式化为微信返回消息能接收的数组形式,即title、description、picurl、url 详见微信官方的文档描述
                        'title' =>$msg['title'],
                        'description' =>$msg['discription'],
                        'picurl' => $msg['pic_url'],
                        'url' =>$msg['url']
                    );




}


}


return $record;
}
?>

PHP 相关文章推荐
模仿OSO的论坛(二)
Oct 09 PHP
PHP使用数组实现队列
Feb 05 PHP
php生成zip压缩文件的方法详解
Jun 09 PHP
解析php中const与define的应用区别
Jun 18 PHP
PHP中的Memcache详解
Apr 05 PHP
thinkphp中memcache的用法实例
Nov 29 PHP
护卫神php套件 php版本升级方法(php5.5.24)
May 10 PHP
浅谈PHP中foreach/in_array的使用
Nov 02 PHP
Zend Framework教程之Autoloading用法详解
Mar 08 PHP
symfony2.4的twig中date用法分析
Mar 18 PHP
PHP巧妙利用位运算实现网站权限管理的方法
Mar 12 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
Mar 26 PHP
php操作MongoDB基础教程(连接、新增、修改、删除、查询)
Mar 25 #PHP
php获取域名的google收录示例
Mar 24 #PHP
php 使用GD库为页面增加水印示例代码
Mar 24 #PHP
php检测useragent版本示例
Mar 24 #PHP
php断点续传之如何分割合并文件
Mar 22 #PHP
php 邮件发送问题解决
Mar 22 #PHP
php数组合并的二种方法
Mar 21 #PHP
You might like
PHP代码审核的详细介绍
2013/06/13 PHP
PHP随机字符串生成代码(包括大小写字母)
2013/06/24 PHP
PHP也能干大事之PHP中的编码解码详解
2015/04/20 PHP
php如何控制用户对图片的访问 PHP禁止图片盗链
2016/03/25 PHP
PHP实现微信商户支付企业付款到零钱功能
2018/09/30 PHP
如何解决PHP获取不到SESSION信息之一般情况
2019/10/10 PHP
浅析jquery的js图表组件highcharts
2014/03/06 Javascript
jQuery操作表格(table)的常用方法、技巧汇总
2014/04/12 Javascript
jquery图片滚动放大代码分享(1)
2015/08/25 Javascript
JavaScript如何实现对数字保留两位小数一位自动补零
2015/12/18 Javascript
JS简单设置下拉选择框默认值的方法
2016/08/20 Javascript
javaScript+turn.js实现图书翻页效果实例代码
2017/02/16 Javascript
javascript ES6中箭头函数注意细节小结
2017/02/17 Javascript
为你的微信小程序体积瘦身详解
2017/05/20 Javascript
关于 angularJS的一些用法
2017/11/29 Javascript
Angular父组件调用子组件的方法
2018/04/02 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
详解如何在webpack中做预渲染降低首屏空白时间
2018/08/22 Javascript
[55:48]VGJ.S vs TNC Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python使用SQLite和Excel操作进行数据分析
2018/01/20 Python
Python中矩阵创建和矩阵运算方法
2018/08/04 Python
在Python中居然可以定义两个同名通参数的函数
2019/01/31 Python
Flask框架路由和视图用法实例分析
2019/11/07 Python
Python中断多重循环的几种方式详解
2020/02/10 Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
2020/03/30 Python
Python confluent kafka客户端配置kerberos认证流程详解
2020/10/12 Python
详解html2canvas截图不能截取圆角图片的解决方案
2018/01/30 HTML / CSS
英国领先的杂志订阅网站:Magazine.co.uk
2018/01/25 全球购物
HEMA法国:荷兰原创设计
2019/02/21 全球购物
80后职场人的职业生涯规划
2014/03/08 职场文书
出资证明书范本(标准版)
2014/09/24 职场文书
教师党的群众路线教育实践活动剖析材料
2014/10/09 职场文书
《天净沙·秋思》教学反思三篇
2019/11/02 职场文书
python数据库批量插入数据的实现(executemany的使用)
2021/04/30 Python
Java基于字符界面的简易收银台
2021/06/26 Java/Android
django中websocket的具体使用
2022/01/22 Python