ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

微信公众号开发-被动回复模式代码php

2021-05-17 00:01:53  阅读:243  来源: 互联网

标签:xml function ch return 微信 被动 private obj php


db.php

<?php
return new PDO("mysql:host=127.0.0.1;dbname=数据库名",'数据库用户名','密码',[
    // 有错误抛异常
    PDO::ERRMODE_EXCEPTION,
    // 以关联数组的形式输出
    PDO::FETCH_ASSOC
]);

被动.php

<?php

$wx = new Wx();
/**
 * 微信被动模式
 */
class Wx
{
    // 自定义token
    private const TOKEN = 'xxx';
    // 数据库对象
    private $pdo;
    // 构造方法
    public function __construct()
    {
        // 是否第一次接入
        if (!empty($_GET['echostr'])) {
            echo $this->checkSigin();
        } else {
            $this->pdo = include './db.php';
            $this->acceptMsg();
        }
    }
    /**
     * 接收公众号发过来的数据
     *
     */
    private function acceptMsg()
    {
        // 获取原生请求数据
        $xml = file_get_contents('php://input');
        $obj = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        // 写日志
        $msgType = $obj['MsgType'];
        // 判断类型处理
        $fun = $msgType . 'Fun';
        // 取消关注不写日志
        if ($obj['Event'] != 'unsubscribe') {
            $this->writeLog($xml);
        }
        echo $this->$fun($obj);
    }
    /**
     * 写日志
     * @param string $xml 写入xml
     * @param int|integer $flag 标识 1:请求 2:发送
     *
     */
    private function writeLog(string $xml, int $flag = 1)
    {
        $flagStr = $flag == 1 ? '请求' : '发送';
        $prevstr = '[' . $flagStr . ']' . date('Y-m-d') . "---------------\n";
        $log = $prevstr . $xml . "\n---------------\n";
        file_put_contents('wx.xml', $log, FILE_APPEND);
    }
    /**
     * 发起请求
     * @param string $url
     * @param string|array       $ret  请求体
     * 
     */
    private function http_req($url, $ret = '')
    {
        
        // 初始化
        $ch = curl_init();
        // 相关设置
        curl_setopt($ch, CURLOPT_URL, $url);
        // 不要请求头
        curl_setopt($ch, CURLOPT_HEADER, 0);
        // 请求结果不直接输出,而是字符串返回
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        # 设置请求超时时间 s
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        # 设置浏览器型号
        curl_setopt($ch, CURLOPT_HEADER, 'MSIE001');
        # 证书不检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        # 设置为post请求
        if ($ret != '') {

            // 开启post
            curl_setopt($ch, CURLOPT_POST, 1);
            // post请求数据
            curl_setopt($ch, CURLOPT_POSTFIELDS, $ret);
        }
        // 发起请求
        $data = curl_exec($ch);

        // 有无发送异常
        if (curl_errno($ch) > 0) {
            // 把错误发送给客户端
            # echo curl_error($ch);
            $data = '';
        }
        // 关闭请求
        curl_close($ch);

        return $data;
    }
    /**
     * 处理回复文本
     *
     */
    private function textFun($obj)
    {
        // 回复文本
        if ($obj['Content'] == '一串文本') {
            return $this->audioFun($obj);
        }elseif (strstr($obj['Content'],'位置-')){
            // 客户端发送指定格式文本 服务端调用后返回
            # 得到关键词
            $kw = str_replace('位置-','',$obj['Content']);
            $kw = trim($kw);
            $url = 'http://api.map.baidu.com/place/v2/search?query='.$kw.'&location=39.915,116.404&radius=2000&output=json&ak=百度ak';
            echo $url;
            $json = $this->http_req($url);
            # json转为数组
            $arr = json_decode($json, true);
            # 判断是否有搜索结果
            if(count($arr['results'])<=0){
                return $this->createText($obj,'没有找到相关服务');
            }
            var_dump($arr['results']);
            $list = '';
            foreach($arr['results'] as $value){
                $list.=($value['name'])."\n";
            }
            return $this->createText($obj,$list);
        }
        $content = '公众号:' . $obj['Content'];
        return $this->createText($obj, $content);
    }
    /**
     * 语音处理
     */
    private function voiceFun($obj)
    {
        $content = (string) $obj['Recognition'];
        $content = ($content) ?? '无解';
        echo $content;
        return $this->createText($obj, $content);
    }
    /**
     * 处理回复语音
     *
     */
    private function audioFun($obj)
    {
        // 回复语音
        $url = 'http://ty.8zl.cn/file/754489012/91376212247374821/M500001QhFgK2RH3J7.mp3';
        $mediaid = '_IiZWnxXTcApusLcp-zIFif5f96yePn4IAvHdbCXhF2DJWKApF9VA1Y_A5WxwG5Q';
        return $this->createAudio($obj, $url, $mediaid);
    }
    /**
     * 处理回复图片
     *
     */
    private function imageFun($obj)
    {
        $mediaid = $obj['MediaId'];
        return $this->createImage($obj, $mediaid);
    }
    /**
     *生成文本信息XML
     */
    private function createText($obj, string $content)
    {
        $xml = '
        <xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[text]]></MsgType>
            <Content><![CDATA[%s]]></Content>
        </xml>
        ';
        // 格式化替换输出
        $str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $content);
        $this->writeLog($str, 2);
        return $str;
    }
    /**
     *生成图片信息XML
     */
    private function createImage($obj, string $mediaid)
    {
        $xml = '
        <xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[image]]></MsgType>
            <Image>
                <MediaId><![CDATA[%s]]></MediaId>
            </Image>
        </xml>
        ';
        // 格式化替换输出
        $str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $mediaid);
        $this->writeLog($str, 2);
        return $str;
    }
    /**
     *生成语音信息XML
     */
    private function createAudio($obj, string $url = '', string $mediaid = '')
    {
        $xml = '
        <xml>
            <ToUserName><![CDATA[%s]]></ToUserName>
            <FromUserName><![CDATA[%s]]></FromUserName>
            <CreateTime>%s</CreateTime>
            <MsgType><![CDATA[music]]></MsgType>
            <Music>
                <Title><![CDATA[xxxx]]></Title>
                <Description><![CDATA[无]]></Description>
                <MusicUrl><![CDATA[%s]]]></MusicUrl>
                <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
                <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
            </Music>
        </xml>';
        // 格式化替换输出
        $str = sprintf($xml, $obj['FromUserName'], $obj['ToUserName'], time(), $url, $mediaid);

        return $str;
    }

    /**
     *  初次接入 检验
     */
    private function checkSigin()
    {
        $input = $_GET;
        $echostr = $input['echostr'];
        $signature = $input['signature'];
        // 数组清除 放临时变量
        unset($input['echostr'], $input['signature']);
        // 数据中添加字段token
        $input['token'] = self::TOKEN;
        // 字典排序
        $tmpStr = implode($input);
        // 加密
        $tmpStr = sha1($tmpStr);

        // 比对
        if ($tmpStr === $signature) {
            return $echostr;
        }
        return '';
    }
    /**
     * 按钮点击事件
     */
    private function clickFun($obj)
    {
        $EventKey = $obj['EventKey'];

        if ('index001' == $EventKey) {
            return $this->createText($obj, '你点击首页按钮');
        } elseif ('kefu001' == $EventKey) {
            return $this->createText($obj, '你点击客服按钮');
        }
        return $this->createText($obj, '无法解决!');
    }

    /**
     * 事件处理
     */
    private function eventFun($obj)
    {
        // 事件名称
        $Event = $obj['Event'];

        switch ($Event) {
            case 'CLICK':
                // 关于点击事件
                return $this->clickFun($obj);
                break;
            case 'LOCATION':
                // 关于点击事件
                $longitude = $obj['Longitude'];
                $latitude = $obj['Latitude'];
                $openid = $obj['FromUserName'];
                // 修改表记录
                $sql = "update fx set longitude=?,latitude=? where openid=?";

                $stmt = $this->pdo->prepare($sql);
                $stmt->execute([$longitude, $latitude, $openid]);

                break;
            case 'subscribe':
                // 如果evnetkey 无值 表示顶级
                $EventKey = ($obj['EventKey']);

                if (empty($EventKey)) {
                    // 首次关注添加数据库
                    $sql = "insert into fx (openid) values (?)";

                    $stmt = $this->pdo->prepare($sql);
                    $stmt->execute([$obj['FromUserName']]);
                } else {
                    # 得到上级id号
                    $id = (int) str_replace('qrscene_', '', $EventKey);
                    # 查询记录
                    $sql = "select * from fx where id=$id";
                    $row = $this->pdo->query($sql)->fetch();

                    # 添加本人记录到数据库
                    $sql = "insert into fx (openid,f1,f2,f3) values(?,?,?,?)";
                    $stmt = $this->pdo->prepare($sql);
                    $openid = $obj['FromUserName'];
                    $stmt->execute([$openid, $row['openid'], $row['f1'], $row['f2']]);
                }
                return $this->createText($obj, "欢迎关注公众平台\n哈哈");
                break;
        }
    }

}

标签:xml,function,ch,return,微信,被动,private,obj,php
来源: https://blog.csdn.net/weixin_42043407/article/details/116905422

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有