微信公众号开发-被动回复模式代码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;
        }
    }

}

Guess you like

Origin blog.csdn.net/weixin_42043407/article/details/116905422