首页 > 代码库 > 微信接口开发之高级篇系列【微信权限封装类】

微信接口开发之高级篇系列【微信权限封装类】

ThinkPHP框架目录结构:

<?php/** * Created by PhpStorm. * User: Tinywan * Date: 2016/9/11 * Time: 9:55 */namespace Org\Util;class WechatAuth{    /* 消息类型常量 */    const MSG_TYPE_TEXT = ‘text‘;    const MSG_TYPE_IMAGE = ‘image‘;    const MSG_TYPE_VOICE = ‘voice‘;    const MSG_TYPE_VIDEO = ‘video‘;    const MSG_TYPE_SHORTVIDEO = ‘shortvideo‘;    const MSG_TYPE_LOCATION = ‘location‘;    const MSG_TYPE_LINK = ‘link‘;    const MSG_TYPE_MUSIC = ‘music‘;    const MSG_TYPE_NEWS = ‘news‘;    const MSG_TYPE_EVENT = ‘event‘;    /* 二维码类型常量 */    const QR_SCENE = ‘QR_SCENE‘;    const QR_LIMIT_SCENE = ‘QR_LIMIT_SCENE‘;    /**     * 微信开发者申请的appID     * @var string     */    private $appId = ‘‘;    /**     * 微信开发者申请的appSecret     * @var string     */    private $appSecret = ‘‘;    /**     * 获取到的access_token     * @var string     */    private $accessToken = ‘‘;    /**     * 微信api根路径     * @var string     */    private $apiURL = ‘https://api.weixin.qq.com/cgi-bin‘;    /**     * 微信二维码根路径     * @var string     */    private $qrcodeURL = ‘https://mp.weixin.qq.com/cgi-bin‘;    //授权地址    private $requestCodeURL = ‘https://open.weixin.qq.com/connect/oauth2/authorize‘;    private $oauthApiURL = ‘https://api.weixin.qq.com/sns‘;    /**     * 构造方法,调用微信高级接口时实例化SDK     * @param string $appid 微信appid     * @param string $secret 微信appsecret     * @param string $token 获取到的access_token     */    public function __construct($appid, $secret, $token = null)    {        if ($appid && $secret) {            $this->appId = $appid;            $this->appSecret = $secret;            if (!empty($token)) $this->accessToken = $token;        } else {            throw new \Exception(‘缺少参数 APP_ID 和 APP_SECRET!‘);        }    }    // 是为了拼接成一URL地址,什么地址,拼接一个    public function getRequestCodeURL($redirect_uri, $state = null, $scope = ‘snsapi_userinfo‘)    {        $query = array(            ‘appid‘ => $this->appId,            ‘redirect_uri‘ => $redirect_uri,            ‘response_type‘ => ‘code‘,            ‘scope‘ => $scope,        );        if (!is_null($state) && preg_match(‘/[a-zA-Z0-9]+/‘, $state)) $query[‘state‘] = $state;        //生成 URL-encode 之后的请求字符串 :foo=bar&baz=boom&cow=milk&php=hypertext+pro        $query = http_build_query($query);        return "{$this->requestCodeURL}?{$query}#wechat_redirect";    }    /**     * 获取access_token,用于后续接口访问     * @return array access_token信息,包含 token 和有效期     */    public function getAccessToken($type = ‘client‘, $code = null)    {        $param = array(            ‘appid‘ => $this->appId,            ‘secret‘ => $this->appSecret        );        switch ($type) {            case ‘client‘:                $param[‘grant_type‘] = ‘client_credential‘;                $url = "{$this->apiURL}/token";                break;            case ‘code‘:                $param[‘code‘] = $code;                $param[‘grant_type‘] = ‘authorization_code‘;                $url = "{$this->oauthApiURL}/oauth2/access_token";                break;            default:                throw new \Exception(‘不支持的grant_type类型!‘);                break;        }        $token = self::http($url, $param);        $token = json_decode($token, true);        if (is_array($token)) {            if (isset($token[‘errcode‘])) {                throw new \Exception($token[‘errmsg‘]);            } else {                $this->accessToken = $token[‘access_token‘];                return $token;            }        } else {            throw new \Exception(‘获取微信access_token失败!‘);        }    }    /**     * 获取授权用户信息     * @param  string $openid 用户的OpenID     * @param  string $lang 指定的语言     * @return array          用户信息数据,具体参见微信文档     */    public function getUserInfo($openid, $lang = ‘zh_CN‘)    {        $query = array(            ‘access_token‘ => $this->accessToken,            ‘openid‘ => $openid,            ‘lang‘ => $lang,        );        $info = self::http("{$this->oauthApiURL}/userinfo", $query);        return json_decode($info, true);    }    /**     * 上传零时媒体资源     * @param  string $filename 媒体资源本地路径     * @param  string $type 媒体资源类型,具体请参考微信开发手册     */    public function mediaUpload($filename, $type)    {        $filename = realpath($filename);        if (!$filename) throw new \Exception(‘资源路径错误!‘);        $data = array(            ‘type‘ => $type,            ‘media‘ => "@{$filename}"        );        return $this->api(‘media/upload‘, $data, ‘POST‘, ‘‘, false);    }    /**     * 上传永久媒体资源     * @param string $filename 媒体资源本地路径     * @param string $type 媒体资源类型,具体请参考微信开发手册     * @param string $description 资源描述,仅资源类型为 video 时有效     */    public function materialAddMaterial($filename, $type, $description = ‘‘)    {        $filename = realpath($filename);        if (!$filename) throw new \Exception(‘资源路径错误!‘);        $data = array(            ‘type‘ => $type,            ‘media‘ => "@{$filename}",        );        if ($type == ‘video‘) {            if (is_array($description)) {                //保护中文,微信api不支持中文转义的json结构                array_walk_recursive($description, function (&$value) {                    $value = urlencode($value);                });                $description = urldecode(json_encode($description));            }            $data[‘description‘] = $description;        }        return $this->api(‘material/add_material‘, $data, ‘POST‘, ‘‘, false);    }    /**     * 获取媒体资源下载地址     * 注意:视频资源不允许下载     * @param  string $media_id 媒体资源id     * @return string           媒体资源下载地址     */    public function mediaGet($media_id)    {        $param = array(            ‘access_token‘ => $this->accessToken,            ‘media_id‘ => $media_id        );        $url = "{$this->apiURL}/media/get?";        return $url . http_build_query($param);    }    /**     * 给指定用户推送信息     * 注意:微信规则只允许给在48小时内给公众平台发送过消息的用户推送信息     * @param  string $openid 用户的openid     * @param  array $content 发送的数据,不同类型的数据结构可能不同     * @param  string $type 推送消息类型     */    public function messageCustomSend($openid, $content, $type = self::MSG_TYPE_TEXT)    {        //基础数据        $data = array(            ‘touser‘ => $openid,            ‘msgtype‘ => $type,        );        //根据类型附加额外数据        $data[$type] = call_user_func(array(self, $type), $content);        return $this->api(‘message/custom/send‘, $data);    }    /**     * 发送文本消息     * @param  string $openid 用户的openid     * @param  string $text 发送的文字     */    public function sendText($openid, $text)    {        return $this->messageCustomSend($openid, $text, self::MSG_TYPE_TEXT);    }    /**     * 发送图片消息     * @param  string $openid 用户的openid     * @param  string $media 图片ID     */    public function sendImage($openid, $media)    {        return $this->messageCustomSend($openid, $media, self::MSG_TYPE_IMAGE);    }    /**     * 发送语音消息     * @param  string $openid 用户的openid     * @param  string $media 音频ID     */    public function sendVoice($openid, $media)    {        return $this->messageCustomSend($openid, $media, self::MSG_TYPE_VOICE);    }    /**     * 发送视频消息     * @param  string $openid 用户的openid     * @param  string $media_id 视频ID     * @param  string $title 视频标题     * @param  string $discription 视频描述     */    public function sendVideo()    {        $video = func_get_args();        $openid = array_shift($video);        return $this->messageCustomSend($openid, $video, self::MSG_TYPE_VIDEO);    }    /**     * 发送音乐消息     * @param  string $openid 用户的openid     * @param  string $title 音乐标题     * @param  string $discription 音乐描述     * @param  string $musicurl 音乐链接     * @param  string $hqmusicurl 高品质音乐链接     * @param  string $thumb_media_id 缩略图ID     */    public function sendMusic()    {        $music = func_get_args();        $openid = array_shift($music);        return $this->messageCustomSend($openid, $music, self::MSG_TYPE_MUSIC);    }    /**     * 发送图文消息     * @param  string $openid 用户的openid     * @param  array $news 图文内容 [标题,描述,URL,缩略图]     * @param  array $news1 图文内容 [标题,描述,URL,缩略图]     * @param  array $news2 图文内容 [标题,描述,URL,缩略图]     *                ...     ...     * @param  array $news9 图文内容 [标题,描述,URL,缩略图]     */    public function sendNews()    {        $news = func_get_args();        $openid = array_shift($news);        return $this->messageCustomSend($openid, $news, self::MSG_TYPE_NEWS);    }    /**     * 发送一条图文消息     * @param  string $openid 用户的openid     * @param  string $title 文章标题     * @param  string $discription 文章简介     * @param  string $url 文章连接     * @param  string $picurl 文章缩略图     */    public function sendNewsOnce()    {        $news = func_get_args();        $openid = array_shift($news);        $news = array($news);        return $this->messageCustomSend($openid, $news, self::MSG_TYPE_NEWS);    }    /**     * 创建用户组     * @param  string $name 组名称     */    public function groupsCreate($name)    {        $data = array(‘group‘ => array(‘name‘ => $name));        return $this->api(‘groups/create‘, $data);    }    /**     * 查询所有分组     * @return array 分组列表     */    public function groupsGet()    {        return $this->api(‘groups/get‘, ‘‘, ‘GET‘);    }    /**     * 查询用户所在的分组     * @param  string $openid 用户的OpenID     * @return number         分组ID     */    public function groupsGetid($openid)    {        $data = array(‘openid‘ => $openid);        return $this->api(‘groups/getid‘, $data);    }    /**     * 修改分组     * @param  number $id 分组ID     * @param  string $name 分组名称     * @return array        修改成功或失败信息     */    public function groupsUpdate($id, $name)    {        $data = array(‘id‘ => $id, ‘name‘ => $name);        return $this->api(‘groups/update‘, $data);    }    /**     * 移动用户分组     * @param  string $openid 用户的OpenID     * @param  number $to_groupid 要移动到的分组ID     * @return array              移动成功或失败信息     */    public function groupsMemberUpdate($openid, $to_groupid)    {        $data = array(‘openid‘ => $openid, ‘to_groupid‘ => $to_groupid);        return $this->api(‘groups/member/update‘, $data);    }    /**     * 用户设备注名     * @param  string $openid 用户的OpenID     * @param  string $remark 设备注名     * @return array          执行成功失败信息     */    public function userInfoUpdateremark($openid, $remark)    {        $data = array(‘openid‘ => $openid, ‘remark‘ => $remark);        return $this->api(‘user/info/updateremark‘, $data);    }    /**     * 获取指定用户的详细信息     * @param  string $openid 用户的openid     * @param  string $lang 需要获取数据的语言     */    public function userInfo($openid, $lang = ‘zh_CN‘)    {        $param = array(‘openid‘ => $openid, ‘lang‘ => $lang);        return $this->api(‘user/info‘, ‘‘, ‘GET‘, $param);    }    /**     * 获取关注者列表     * @param  string $next_openid 下一个openid,在用户数大于10000时有效     * @return array               用户列表     */    public function userGet($next_openid = ‘‘)    {        $param = array(‘next_openid‘ => $next_openid);        return $this->api(‘user/get‘, ‘‘, ‘GET‘, $param);    }    /**     * 创建自定义菜单     * @param  array $button 符合规则的菜单数组,规则参见微信手册     */    public function menuCreate($button)    {        $data = array(‘button‘ => $button);        return $this->api(‘menu/create‘, $data);    }    /**     * 获取所有的自定义菜单     * @return array  自定义菜单数组     */    public function menuGet()    {        return $this->api(‘menu/get‘, ‘‘, ‘GET‘);    }    /**     * 删除自定义菜单     */    public function menuDelete()    {        return $this->api(‘menu/delete‘, ‘‘, ‘GET‘);    }    /**     * 创建二维码,可创建指定有效期的二维码和永久二维码     * @param  integer $scene_id 二维码参数     * @param  integer $expire_seconds 二维码有效期,0-永久有效     */    public function qrcodeCreate($scene_id, $expire_seconds = 0)    {        $data = array();        if (is_numeric($expire_seconds) && $expire_seconds > 0) {            $data[‘expire_seconds‘] = $expire_seconds;            $data[‘action_name‘] = self::QR_SCENE;        } else {            $data[‘action_name‘] = self::QR_LIMIT_SCENE;        }        $data[‘action_info‘][‘scene‘][‘scene_id‘] = $scene_id;        return $this->api(‘qrcode/create‘, $data);    }    /**     * 根据ticket获取二维码URL     * @param  string $ticket 通过 qrcodeCreate接口获取到的ticket     * @return string         二维码URL     */    public function showqrcode($ticket)    {        return "{$this->qrcodeURL}/showqrcode?ticket={$ticket}";    }    /**     * 长链接转短链接     * @param  string $long_url 长链接     * @return string           短链接     */    public function shorturl($long_url)    {        $data = array(            ‘action‘ => ‘long2short‘,            ‘long_url‘ => $long_url        );        return $this->api(‘shorturl‘, $data);    }    /**     * 调用微信api获取响应数据     * @param  string $name API名称     * @param  string $data POST请求数据     * @param  string $method 请求方式     * @param  string $param GET请求参数     * @return array          api返回结果     */    protected function api($name, $data = ‘‘, $method = ‘POST‘, $param = ‘‘, $json = true)    {        $params = array(‘access_token‘ => $this->accessToken);        if (!empty($param) && is_array($param)) {            $params = array_merge($params, $param);        }        $url = "{$this->apiURL}/{$name}";        if ($json && !empty($data)) {            //保护中文,微信api不支持中文转义的json结构            array_walk_recursive($data, function (&$value) {                $value = urlencode($value);            });            $data = urldecode(json_encode($data));        }        $data = self::http($url, $params, $data, $method);        return json_decode($data, true);    }    /**     * 发送HTTP请求方法,目前只支持CURL发送请求     * @param  string $url 请求URL     * @param  array $param GET参数数组     * @param  array $data POST的数据,GET请求时该参数无效     * @param  string $method 请求方法GET/POST     * @return array          响应数据     */    protected static function http($url, $param, $data = ‘‘, $method = ‘GET‘)    {        $opts = array(            CURLOPT_TIMEOUT => 30,            CURLOPT_RETURNTRANSFER => 1,            CURLOPT_SSL_VERIFYPEER => false,            CURLOPT_SSL_VERIFYHOST => false,        );        /* 根据请求类型设置特定参数 */        $opts[CURLOPT_URL] = $url . ‘?‘ . http_build_query($param);        if (strtoupper($method) == ‘POST‘) {            $opts[CURLOPT_POST] = 1;            $opts[CURLOPT_POSTFIELDS] = $data;            if (is_string($data)) { //发送JSON数据                $opts[CURLOPT_HTTPHEADER] = array(                    ‘Content-Type: application/json; charset=utf-8‘,                    ‘Content-Length: ‘ . strlen($data),                );            }        }        /* 初始化并执行curl请求 */        $ch = curl_init();        curl_setopt_array($ch, $opts);        $data = curl_exec($ch);        $error = curl_error($ch);        curl_close($ch);        //发生错误,抛出异常        if ($error) throw new \Exception(‘请求发生错误:‘ . $error);        return $data;    }    /**     * 构造文本信息     * @param  string $content 要回复的文本     */    private static function text($content)    {        $data[‘content‘] = $content;        return $data;    }    /**     * 构造图片信息     * @param  integer $media 图片ID     */    private static function image($media)    {        $data[‘media_id‘] = $media;        return $data;    }    /**     * 构造音频信息     * @param  integer $media 语音ID     */    private static function voice($media)    {        $data[‘media_id‘] = $media;        return $data;    }    /**     * 构造视频信息     * @param  array $video 要回复的视频 [视频ID,标题,说明]     */    private static function video($video)    {        $data = array();        list(            $data[‘media_id‘],            $data[‘title‘],            $data[‘description‘],            ) = $video;        return $data;    }    /**     * 构造音乐信息     * @param  array $music 要回复的音乐[标题,说明,链接,高品质链接,缩略图ID]     */    private static function music($music)    {        $data = array();        list(            $data[‘title‘],            $data[‘description‘],            $data[‘musicurl‘],            $data[‘hqmusicurl‘],            $data[‘thumb_media_id‘],            ) = $music;        return $data;    }    /**     * 构造图文信息     * @param  array $news 要回复的图文内容     * [     *      0 => 第一条图文信息[标题,说明,图片链接,全文连接],     *      1 => 第二条图文信息[标题,说明,图片链接,全文连接],     *      2 => 第三条图文信息[标题,说明,图片链接,全文连接],     * ]     */    private static function news($news)    {        $articles = array();        foreach ($news as $key => $value) {            list(                $articles[$key][‘title‘],                $articles[$key][‘description‘],                $articles[$key][‘url‘],                $articles[$key][‘picurl‘]                ) = $value;            if ($key >= 9) break; //最多只允许10条图文信息        }        $data[‘articles‘] = $articles;        return $data;    }}

 

微信接口开发之高级篇系列【微信权限封装类】