【原】微信开发基类代码分享
in 代码片段 with 0 comment

【原】微信开发基类代码分享

in 代码片段 with 0 comment

代码来源:自己整理编写
说明:说到微信开发,说到底核心技术难点有3个。1、微信平台接入;2、xml数据组装;3、PHP调用API接口。为此我简单的封装了一个解决类,已被多少次使用证明其稳定性,所以,在此分享一下,有需要的拿走。类已经支持了加密消息,以后随着微信的发展,接口的更新,也会做相应的升级。

<?php
/**
 * Created by PhpStorm.
 * User: zhaoxiang
 * Date: 15/11/12
 * Time: 下午11:30
 */

namespace Wechat\Controller;
use Common\Controller\CommonController;
use Wechat\Wxcpt\WxCrypt;


class WechatController extends CommonController{

    protected $encodingAesKey;
    protected $token;
    protected $corpId;
    protected $getData;
    protected $corpsecret;
    private $Is_Crypt = true;

    /**
     * 验证函数
     * 用于生成消息签名
     * @access public
     * @param array $_GET 通过GET传递过来的参数
     */
    protected function validate(){

        $sVerifyMsgSig = $_GET['msg_signature'];
        $sVerifyTimeStamp = $_GET['timestamp'];
        $sVerifyNonce = $_GET['nonce'];
        $sVerifyEchoStr = $_GET['echostr'];

        // 需要返回的明文
        $sEchoStr = "";
        $wxcpt = new WxCrypt($this->token, $this->encodingAesKey, $this->corpId);
        $errCode = $wxcpt->VerifyURL($sVerifyMsgSig, $sVerifyTimeStamp, $sVerifyNonce, $sVerifyEchoStr, $sEchoStr);
        if ($errCode == 0) {
            echo $sEchoStr;
            exit;
        } else {
            echo("ERR: " . $errCode . "\n\n");
            exit;
        }

    }


    /**
     * 消息预处理,对微信服务器发过来的数据进行预处理
     * @return array
     */
    protected function GetMessage(){
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

        libxml_disable_entity_loader(true);
        $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $postArr=(array)$postObj;

        $postXml=$this->getPlaintext($postArr);
        if(is_numeric($postXml)){
            $this->SendMessage('系统错误!错误代码为:'.$postXml,'text');
        }
        $postObj = simplexml_load_string($postXml, 'SimpleXMLElement', LIBXML_NOCDATA);
        $postArr=(array)$postObj;

        $this->getData=$postArr;
        return $postArr;
    }

    /**
     * 消息发送函数
     * 对于发送不同类型消息,自动分配对应消息类型方法
     * @access public
     * @param array|string $array 用户需要发送的消息内容。
     * @param string $type 用户需要发送消息的类型。
     */
    public function SendMessage($array,$type){
        $type=strtolower($type);

        switch($type){
            case 'text':
                $this->TextMessage($array);
                break;
            case 'music':
                $this->MusicMessage($array);
                break;
            case 'news':
                $this->NewsMessage($array);
                break;
            case 'image':
                $this->ImageMessage($array);
                break;
            case 'voice':
                $this->VoiceMessage($array);
                break;
            case 'video':
                $this->VideoMessage($array);
                break;
        }

    }

    /**
     * 文本发送函数
     * 按照固定格式组合待发文本消息的数组,并且进行一定程度的信息过滤
     * @access private
     * @return 成功返回true 失败返回false
     */
    private function TextMessage($array){
        if(is_array($array)||is_object($array)){
            $contentStr = "系统错误!错误代码为:80003";
        }else{
            $contentStr = $array;
        }
        $data=array(
            'ToUserName'=>$this->getData['FromUserName'],
            'FromUserName'=>$this->getData['ToUserName'],
            'CreateTime'=>NOW_TIME,
            'MsgType'=>'text'
        );

        $data['Content']=$contentStr;
        $resultStr = '<xml>'.$this->data2xml($data).'</xml>';

        //调用加密算法
        if($this->Is_Crypt){
            $resultStr=$this->getPassword($resultStr);
            if(is_numeric($resultStr)){
                $this->SendMessage('系统错误!错误代码为:'.$resultStr,'test');
            }
        }

        exit($resultStr);
    }

    /**
     * 音乐发送函数
     * 按照固定格式组合待发音乐消息的数组,并且进行一定程度的信息过滤
     * @access private
     * @return 成功返回true 失败返回false
     */
    private function MusicMessage($array){
        if(!is_array($array)&&!is_object($array)){
            $this->TextMessage ("系统错误!错误代码为:80003");
        }else{
            $name_arr=array('Title','Description','MusicUrl','HQMusicUrl');
            foreach($array as $key => $value){
                $data_next['Music'][$name_arr[$key]]=$value;
            }
        }
        $data=array(
            'ToUserName'=>$this->getData['FromUserName'],
            'FromUserName'=>$this->getData['ToUserName'],
            'CreateTime'=>NOW_TIME,
            'MsgType'=>'music'
        );
        $data=array_merge($data,$data_next);

        $resultStr = '<xml>'.$this->data2xml($data).'<FuncFlag>0</FuncFlag></xml>';

        //启用加密状态时候调用加密算法
        if($this->Is_Crypt){
            $resultStr=$this->getPassword($resultStr);
            if(is_numeric($resultStr)){
                $this->SendMessage('系统错误!错误代码为:'.$resultStr,'test');
            }
        }

        exit($resultStr);
    }

    /**
     * 图文发送函数
     * 按照固定格式组合待发图文消息的数组,并且进行一定程度的信息过滤
     * @access private
     * @return 成功返回true 失败返回false
     */
    private function NewsMessage($array){
        if(!is_array($array)&&!is_object($array)){
            $this->TextMessage ("系统错误!错误代码为:80003");
        }else{
            $data_next['ArticleCount']=count($array);
            if($data_next['ArticleCount']>10){
                $this->TextMessage ("系统错误!错误代码为:40000");
            }
            $name_arr=array('Title','Description','PicUrl','Url');
            foreach($array as $key => $value){
                foreach($value as $kk => $val){
                    $data_next['Articles'][$key][$name_arr[$kk]]=$val;
                }
            }
        }
        $data=array(
            'ToUserName'=>$this->getData['FromUserName'],
            'FromUserName'=>$this->getData['ToUserName'],
            'CreateTime'=>NOW_TIME,
            'MsgType'=>'news'
        );
        $data=array_merge($data,$data_next);
        $resultStr = '<xml>'.$this->data2xml($data).'<FuncFlag>0</FuncFlag></xml>';

        //启用加密状态时候调用加密算法
        if($this->Is_Crypt){
            $resultStr=$this->getPassword($resultStr);
            if(is_numeric($resultStr)){
                $this->SendMessage('系统错误!错误代码为:'.$resultStr,'test');
            }
        }

        exit($resultStr);
    }

    //以下需要先将要发送的资源上传微信服务器,获取MediaId,所以只对群发功能适用
    //图片发送方法
    private function ImageMessage($array){

        $data=array(
            'ToUserName'=>$this->getData['FromUserName'],
            'FromUserName'=>$this->getData['ToUserName'],
            'CreateTime'=>NOW_TIME,
            'MsgType'=>'image'
        );

        //$data['Image']['MediaId']=$array['MediaId'];
        $resultStr = '<xml>'.$this->data2xml($data).'</xml>';

        //调用加密算法
        if($this->Is_Crypt){
            $resultStr=$this->getPassword($resultStr);
            if(is_numeric($resultStr)){
                $this->SendMessage('系统错误!错误代码为:'.$resultStr,'test');
            }
        }

        exit($resultStr);
    }
    //语音发送方法
    private function VoiceMessage(){

     }
    //视频发送方法
    private function VideoMessage(){

     }

    /**
     * Xml组合函数
     * 用于将数组的转换成XML格式的字符串
     * @access private
     * @param array $data 需要转换格式的数组
     * @return string $xml 转换完成后的XML格式字符串
     */
    private function data2xml($data){
        $xml='';
        foreach($data as $key=>$val) {
            is_numeric($key) && $key="item";
            $xml.="<$key>";
            if(is_array($val)||is_object($val)){
                $xml.=$this->data2xml($val);
            }else{
                if($key=="CreateTime"||$key=="ArticleCount"){
                    $xml.=$val;
                }else{
                    $xml.='<![CDATA['.$val.']]>';
                }
            }
            list($key,)=explode(' ',$key);
            $xml.="</$key>";
        }
        return $xml;
    }

    //TODO::上传资源(语音,视频,图片),获取MediaId
    private function SendFile(){

     }

    /**
     * 加密函数
     * 在启用加密状态时候对即将发送的XML格式消息进行加密处理
     * @access private
     * @param string $mesxml 在不加密情况下按照固定格式组装好的xml格式字符串
     * @return int|string  $encryptMsg|$errCode 成功的时候返回加密好的字符串  失败时候返回错误代码
     */
    private function getPassword($sRespData){
        $sReqTimeStamp = $_GET['timestamp'];
        $sReqNonce = $_GET['nonce'];

        $sEncryptMsg = ""; //xml格式的密文
        $wxcpt = new WxCrypt($this->token, $this->encodingAesKey, $this->corpId);
        $errCode = $wxcpt->EncryptMsg($sRespData, $sReqTimeStamp, $sReqNonce, $sEncryptMsg);
        if ($errCode == 0) {
            return $sEncryptMsg;
        } else {
            return $errCode;
        }
    }

    /**
     * 解密函数
     * 在启用加密状态时候对即将发送的XML格式消息进行加密处理
     * @access private
     * @param string $mesxml 在不加密情况下按照固定格式组装好的xml格式字符串
     * @return int|string  $encryptMsg|$errCode 成功的时候返回加密好的字符串  失败时候返回错误代码
     */
    private function getPlaintext($sReqData){

        $sReqMsgSig = $this->getData['MsgSignature']?$this->getData['MsgSignature']:$_GET['msg_signature'];
        $sReqTimeStamp = $this->getData['TimeStamp']?$this->getData['TimeStamp']:$_GET['timestamp'];
        $sReqNonce = $this->getData['Nonce']?$this->getData['Nonce']:$_GET['nonce'];

        $sMsg = "";
        $wxcpt = new WxCrypt($this->token, $this->encodingAesKey, $this->corpId);
        $errCode = $wxcpt->DecryptMsg($sReqMsgSig, $sReqTimeStamp, $sReqNonce, $sReqData, $sMsg);
        if ($errCode == 0) {
            return $sMsg;
        } else {
            return $errCode;
        }
    }

}
Comments are closed.