欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-10-18 17:31:45
一、写好接口程序 在你的服务器上上传好一个接口程序文件,如http://www.yourdomain.com/weixin.php  内容如下: 复制代码 代...

一、写好接口程序

在你的服务器上上传好一个接口程序文件,如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填上面的,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;
}
?>