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 相关文章推荐
关于文本留言本的分页代码
Oct 09 PHP
介绍php设计模式中的工厂模式
Jun 12 PHP
用PHP实现的四则运算表达式计算实现代码
Aug 02 PHP
DOM XPATH获取img src值的query
Sep 23 PHP
php对数组排序的简单实例
Dec 25 PHP
2014年10个最佳的PHP图像操作库
Jul 14 PHP
PHP中strcmp()和strcasecmp()函数字符串比较用法分析
Jan 07 PHP
php强大的时间转换函数strtotime
Feb 18 PHP
thinkPHP分组后模板无法加载问题解决方法
Jul 12 PHP
php readfile下载大文件失败的解决方法
May 22 PHP
Laravel框架下载,安装及路由操作图文详解
Dec 04 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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
星际争霸 Starcraft 编年史
2020/03/14 星际争霸
php5 apache 2.2 webservice 创建与配置(java)
2011/01/27 PHP
thinkphp控制器调度使用示例
2014/02/24 PHP
yii2.0之GridView自定义按钮和链接用法
2014/12/15 PHP
php动态生成缩略图并输出显示的方法
2015/04/20 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
2017年最好用的9个php开发工具推荐(超好用)
2017/10/23 PHP
JavaScript Event学习第三章 早期的事件处理程序
2010/02/07 Javascript
比较搞笑的js陷阱题
2010/02/07 Javascript
jQuery读取XML文件内容的方法
2015/03/09 Javascript
js实现的彩色方块飞舞奇幻效果
2016/01/27 Javascript
Vue.js学习笔记之 helloworld
2016/08/14 Javascript
RGB和YUV 多媒体编程基础详细介绍
2016/11/04 Javascript
基于Vue2的独立构建与运行时构建的差别(详解)
2017/12/06 Javascript
vue通过路由实现页面刷新的方法
2018/01/25 Javascript
详解实现一个通用的“划词高亮”在线笔记功能
2019/04/23 Javascript
Angular实现svg和png图片下载实现
2019/05/05 Javascript
webpack实践之DLLPlugin 和 DLLReferencePlugin的使用教程
2019/06/10 Javascript
微信小程序图片左右摆动效果详解
2019/07/13 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
nodejs中内置模块fs,path常见的用法说明
2020/11/07 NodeJs
教你如何在Django 1.6中正确使用 Signal
2014/06/22 Python
Python实现读取并保存文件的类
2017/05/11 Python
Tensorflow之梯度裁剪的实现示例
2020/03/08 Python
Python如何实现的二分查找算法
2020/05/27 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
2020/08/26 Python
python向xls写入数据(包括合并,边框,对齐,列宽)
2021/02/02 Python
详解HTML5中download属性的应用
2015/08/06 HTML / CSS
影视制作岗位职责
2013/12/04 职场文书
求职信范文英文版
2014/01/05 职场文书
2014年党务公开方案
2014/05/08 职场文书
MySQL入门命令之函数-单行函数-流程控制函数
2021/04/05 MySQL
python模板入门教程之flask Jinja
2022/04/11 Python
Redis 异步机制
2022/05/15 Redis
本地搭建minio文件服务器(使用bat脚本启动)的方法
2022/07/15 Servers