PHP 微信公众号基本操作类


 目前已集成:

  1. 接收、回复被动消息
  2. 创建自定义菜单
  3. 获取用户基本信息
  4. 网页授权并获取用户基本信息
  5. 调用微信JS-SDK

 

<?php
/**
 * 微信公众号基本操作类
 * 作者:何效名
 */

class WeChat
{
    private $appId = '';
    private $appSecret = '';

    private $jsApiList = [];
    private $jsHtmlList = [];

    public function __construct($appId, $appSecret)
    {
        $this -> appId = $appId;
        $this -> appSecret = $appSecret;
    }

    /**
     * 被动接收消息
     */
    public function getMessage()
    {
        if($_SERVER['REQUEST_METHOD'] == 'GET' && isset($_GET["signature"]))
        {
            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];
            
            $tmpArr = array('xmsb520', $timestamp, $nonce);
            sort($tmpArr, SORT_STRING);
            $tmpStr = implode($tmpArr);
            $tmpStr = sha1($tmpStr);
            
            if($tmpStr == $signature)
            {
                return $_GET['echostr'];
            }
            else
            {
                return false;
            }
        }
        
        if($xml = file_get_contents('php://input'))
        {
            $this -> writeMsg($xml, 'getMessage');
            
            return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        }
        
        return false;
    }

    /**
     * 回复被动消息
     */
    public function replyMessage($ToUserName, $FromUserName, $ContentArr)
    {
        $dataArr = [];
        $dataArr['ToUserName'] = $ToUserName;
        $dataArr['FromUserName'] = $FromUserName;
        $dataArr['CreateTime'] = time();
        
        $dataArr = array_merge($dataArr, $ContentArr);
        
        $dataXml = $this -> arr2xml($dataArr);
        return $dataXml;
    }

    /**
     * 生成消息主体
     */
    public function createTextMessage($Content)
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'text';
        $messageArr['Content'] = $Content;
        
        return $messageArr;
    }

    public function createImageMessage($MediaId)
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'image';
        $messageArr['Image'] = [];
        $messageArr['Image']['MediaId'] = $MediaId;
        
        return $messageArr;
    }

    public function createVoiceMessage($MediaId)
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'voice';
        $messageArr['Voice'] = [];
        $messageArr['Voice']['MediaId'] = $MediaId;
        
        return $messageArr;
    }

    public function createVideoMessage($MediaId, $Title = '', $Description = '')
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'video';
        $messageArr['Video'] = [];
        $messageArr['Video']['MediaId'] = $MediaId;
        $messageArr['Video']['Title'] = $Title;
        $messageArr['Video']['Description'] = $Description;
        
        return $messageArr;
    }

    public function createMusicMessage($ThumbMediaId, $Title = '', $Description = '', $MusicURL = '', $HQMusicUrl = '')
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'music';
        $messageArr['Music'] = [];
        $messageArr['Music']['ThumbMediaId'] = $ThumbMediaId;
        $messageArr['Music']['Title'] = $Title;
        $messageArr['Music']['Description'] = $Description;
        $messageArr['Music']['MusicURL'] = $MusicURL;
        $messageArr['Music']['HQMusicUrl'] = $HQMusicUrl;
        
        return $messageArr;
    }

    public function createNewsMessage($Title, $Description, $PicUrl, $Url)
    {
        $messageArr = [];
        $messageArr['MsgType'] = 'news';
        $messageArr['Articles'] = [];
        
        if(!is_array($Title))
        {
            $messageArr['ArticleCount'] = 1;
            $messageArr['Articles']['item'] = [];
            $messageArr['Articles']['item']['Title'] = $Title;
            $messageArr['Articles']['item']['Description'] = $Description;
            $messageArr['Articles']['item']['PicUrl'] = $PicUrl;
            $messageArr['Articles']['item']['Url'] = $Url;
        }
        else
        {
            $messageArr['ArticleCount'] = count($Title);
            
            foreach($Title as $key => $value)
            {
                $tmpArr = [];
                $tmpArr['item'] = [];
                $tmpArr['item']['Title'] = $Title[$key];
                $tmpArr['item']['Description'] = $Description[$key];
                $tmpArr['item']['PicUrl'] = $PicUrl[$key];
                $tmpArr['item']['Url'] = $Url[$key];
                
                $messageArr['Articles'][] = $tmpArr;
            }
        }
        
        return $messageArr;
    }

    /**
     * 创建自定义菜单
     */
    public function createMenu($menuData = [])
    {
        $accessToken = $this -> getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$accessToken}";
        
        if(empty($menuData))
        {
            $menuData =
            [
                'button' =>
                [
                    [
                        'type' => 'click',
                        'name' => '菜单',
                        'key' => 'xmsb'
                    ],
                    [
                        'name' => '多级菜单',
                        'sub_button' =>
                        [
                            [
                                'type' => 'view',
                                'name' => '跳转链接',
                                'url' => 'http://www.baidu.com'
                            ],
                            [
                                'type' => 'view',
                                'name' => '跳转链接',
                                'url' => 'http://www.soso.com'
                            ]
                        ]
                    ]
                ]
            ];
        }
        
        $menuData = json_encode($menuData, JSON_UNESCAPED_UNICODE);
        $header = 
        [
            'Content-Type: application/json',
            'Content-Length: ' . strlen($menuData)
        ];
        
        $result = $this -> curl($url, $menuData, $header);
        $result = json_decode($result, true);
        
        if($result['errcode'] == 0)
        {
            return true;
        }
        else
        {
            $this -> writeError($result, 'createMenu');
            
            return false;
        }
    }

    /**
     * 获取用户基本信息
     */
    public function getUserInfo($openId)
    {
        if($accessToken = $this -> getAccessToken())
        {
            $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$accessToken}&openid={$openId}&lang=zh_CN";
            
            $result = $this -> curl($url);
            $result = json_decode($result, true);
            
            if(empty($result['errcode']))
            {
                return $result;
            }
            else
            {
                $this -> writeError($result, 'getUserInfo');
                
                return false;
            }
        }
        else
        {
            return false;
        }
    }

    /**
     * 网页授权并获取用户信息
     */
    public function getWebUserinfo()
    {
        if(empty($_GET['code']))
        {
            $appId = $this -> appId;
            
            $thisUrl = $this -> getUrl();
            $redirectUri = urlencode($thisUrl);
            
            $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appId}&redirect_uri={$redirectUri}&response_type=code&scope=snsapi_userinfo#wechat_redirect";
            header("Location:" . $url);
            die();
        }
        else
        {
            if($accessToken = $this -> getWebAccessToken($_GET['code']))
            {
                $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$accessToken['access_token']}&openid={$accessToken['openid']}&lang=zh_CN";
                
                $result = $this -> curl($url);
                $result = json_decode($result, true);
                
                if(empty($result['errcode']))
                {
                    $result['openid'] = $accessToken['openid'];
                    
                    return $result;
                }
                else
                {
                    $this -> writeError($result, 'getWebUserinfo');
                    
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }

    /**
     * 调用JS-SDK
     */
    public function addJsApi($jsArea)
    {
        $jsArea = trim($jsArea);
        preg_match("/^wx\.(\w+)/", $jsArea, $result);
        
        if(!empty($result[1]))
        {
            $this -> jsApiList[] = $result[1];
            $this -> jsHtmlList[] = $jsArea;
            
            return $this;
        }
        else
        {
            $this -> writeError('wx.接口正则匹配失败', 'addJsApi');
            
            return false;
        }
    }

    public function createJsHtml($debug = false)
    {
        $debug = $debug ? 'true' : 'false';
        
        if(!empty($this -> jsApiList))
        {
            $time = time();
            $jsApiListStr = "['" . implode("', '", $this -> jsApiList) . "']";
            $jsNonceStr = 'xmsb_' . mt_rand(10000, 99999) . chr(mt_rand(65, 90));
            
            if($signStr = $this -> getJsSign($jsNonceStr))
            {
                $htmlArea = <<<xmsb
                <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js" type="text/javascript" charset="utf-8"></script>
                <script type="text/javascript">
                    wx.config(
                    {
                        debug: {$debug},
                        appId: '{$this -> appId}',
                        timestamp: {$time},
                        nonceStr: '{$jsNonceStr}',
                        signature: '{$signStr}',
                        jsApiList: {$jsApiListStr}
                    });
                    
                    wx.ready(function()
                    {
xmsb;
foreach($this -> jsHtmlList as $html) { $htmlArea .= "\n" . $html; } $htmlArea .= <<<xmsb }); </script> xmsb; return $htmlArea; } else { return false; } } else { $this -> writeError('未添加要调用的wx.接口', 'createJsHtml'); return false; } } /** * 获取Access token */ private function getAccessToken() { if(empty($_COOKIE['wechat_cookie_' . $_SERVER['SERVER_NAME']])) { if($accessToken = $this -> refreshAccessToken()) { return $accessToken; } else { return false; } } else { return $_COOKIE['wechat_cookie_' . $_SERVER['SERVER_NAME']]; } } /** * 获取网页授权Access token */ private function getWebAccessToken($code) { $appId = $this -> appId; $appSecret = $this -> appSecret; $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appId}&secret={$appSecret}&code={$code}&grant_type=authorization_code"; $result = $this -> curl($url); $result = json_decode($result, true); if(empty($result['errcode'])) { return $result; } else { $this -> writeError($result, 'getWebAccessToken'); return false; } } /** * 获取JS-SDK签名 */ private function getJsSign($jsNonceStr) { if($accessToken = $this -> getAccessToken()) { $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={$accessToken}&type=jsapi"; $result = $this -> curl($url); $result = json_decode($result, true); if(empty($result['errcode'])) { $signArr = [ 'noncestr' => $jsNonceStr, 'jsapi_ticket' => $result['ticket'], 'timestamp' => time(), 'url' => $this -> getUrl() ]; ksort($signArr); $signStr = ''; foreach($signArr as $key => $value) { $signStr .= "{$key}={$value}&"; } $signStr = sha1(trim($signStr, '&')); return $signStr; } else { $this -> writeError($result, 'getJsSign'); return false; } } else { return false; } } /** * 刷新Access token */ private function refreshAccessToken() { $appId = $this -> appId; $appSecret = $this -> appSecret; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}"; $result = $this -> curl($url); $result = json_decode($result, true); if(empty($result['errcode'])) { setcookie('wechat_cookie_' . $_SERVER['SERVER_NAME'], $result['access_token'], time() + $result['expires_in'] - 100); return $result['access_token']; } else { $this -> writeError($result, 'refreshAccessToken'); return false; } } /** * 获取当前URL */ private function getUrl() { $url = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; if($_SERVER['SERVER_PORT'] != '80') { $url .= $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT'] . $_SERVER['REQUEST_URI']; } else { $url .= $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']; } return $url; } /** * 数组转XML */ private function arr2xml($array, $root = true) { $str = ""; if($root) $str .= "<xml>"; foreach($array as $key => $val) { if(is_array($val)) { if(is_numeric($key)) { $trueKey = key($val); $child = $this -> arr2xml($val[$trueKey], false); $str .= "<{$trueKey}>{$child}</{$trueKey}>"; } else { $child = $this -> arr2xml($val, false); $str .= "<{$key}>{$child}</{$key}>"; } } else { if($key == 'CreateTime') { $str .= "<{$key}>{$val}</{$key}>"; } else { $str .= "<{$key}><![CDATA[{$val}]]></{$key}>"; } } } if($root) $str .= "</xml>"; return $str; } /** * 记录日志 */ private function writeLog($data, $fileName) { $dir = './wechat_log/' . date('Y-m') . '/' . date('d') . '/'; $path = $dir . $fileName . '_' . date('H') . '.txt'; if(!file_exists($dir)) { $res = mkdir(iconv('UTF-8', 'GBK', $dir), 0777, true); } $fp = fopen($path, 'a'); $time = '['.date('Y-m-d H:i:s').'] '; $text = var_export($data, true); fwrite($fp, $time.$text."\r\n"); fclose($fp); } private function writeMsg($msg, $method) { $this -> writeLog("{$method} Info:", 'message_log'); $this -> writeLog($msg, 'message_log'); $this -> writeLog("\n", 'message_log'); } private function writeError($errorMsg, $method) { $this -> writeLog("{$method} Error:", 'error_log'); $this -> writeLog($errorMsg, 'error_log'); $this -> writeLog("\n", 'error_log'); } /** * 发送curl */ private function curl($url, $data = [], $header = []) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); if(!empty($header)) { curl_setopt($curl, CURLOPT_HTTPHEADER, $header); } curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); if(!empty($data)) { curl_setopt($curl, CURLOPT_POST, 1); if(is_array($data)) { curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); } else { curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } } curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($curl); curl_close($curl); return $result; } }

 


使用方式:

// 引用文件并实例化
require_once('./WeChat.php');
$weChat = new \WeChat('appid', 'secret');
// 接收、回复被动消息
$getMessage = $weChat -> getMessage();

if($getMessage['MsgType'] == 'event' && $getMessage['EventKey'] == 'jianjie')
{
    $content = '公众号简介';
    
    $message = $weChat -> createTextMessage($content);
    $data = $weChat -> replyMessage($getMessage['FromUserName'], $getMessage['ToUserName'], $message);
    
    return $data;
}
// 创建自定义菜单
$menuData =
[
    'button' =>
    [
        [
            'type' => 'click',
            'name' => '公众号简介',
            'key' => 'jianjie'
        ],
        [
            'type' => 'view',
            'name' => '官方网站',
            'url' => 'https://www.baidu.com'
        ]
    ]
];

$createMenu = $weChat -> createMenu($menuData);
var_dump($createMenu);
// 获取用户基本信息
$userInfo = $weChat -> getUserInfo('openid');
var_dump($userInfo);
// 网页授权并获取用户基本信息
$userInfo = $weChat -> getWebUserinfo();
var_dump($userInfo);
// 调用微信JS-SDK
$api1 = <<<xmsb
wx.updateAppMessageShareData(
{ 
    title: '标题',
    desc: '描述描述描述描述',
    link: 'http://www.baidu.com', 
    imgUrl: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
    success: function()
    {
        alert('success1');
    }
})
xmsb;

$api2 = <<<xmsb
wx.updateTimelineShareData(
{ 
    title: '标题',
    link: 'http://www.baidu.com', 
    imgUrl: 'https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png',
    success: function()
    {
        alert('success2');
    }
})
xmsb;

$js = $weChat -> addJsApi($api1) -> addJsApi($api2) -> createJsHtml();

echo "xmsb <br />";
echo $js;

 

posted @ 2021-05-12 13:54  何效名  阅读(360)  评论(1编辑  收藏  举报