代码来源:自己整理编写
说明:说到微信开发,说到底核心技术难点有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;
}
}
}
本文由 陌上花开 创作,采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名
最后编辑时间为: Jul 1, 2016 at 04:10 am