(原创)微信公众号开发的简单模板及配置流程简介

/*

*公司需要,学了一下微信公众号开发,写这篇博客的时候已经开发结束半个月了

*回来记录一下,采用php语言(现学的)进行开发,不足之处还望提出来共同探讨

*/


(原创不易,转载请注明出处!)


提示:目前微信公众号包含订阅号和服务号两种。详细区别官网有介绍,这里要说的是订阅号如果自己配置服务器url的话,是没有自定义菜单栏功能的,因此配置服务器url后只能接受用户的手动输入内容。而服务号需要企业认证,个人无法申请。


一、微信开发环境搭建

1.申请和配置微信公众平台

    微信公众平台已经提供了一个很便捷的开发配置方式,这里不在赘述,展示一下配置完的画面,

    切记,图中画红色圈的地方一定要点击启用,否则微信客户端的请求无法发送到我们配置的服务器地址。我在这里浪费了一早上的时间,醉了。。。。




2.微信请求的传递流程

    稍微解释一下,微信的服务器只是起到转发的作用,将手机客户端的请求转发到我们配置的服务器地址,就是上图看到URL地址。


3.服务器地址文件的编写

    这个才是开发的重点啊,下面先贴上本人编写的源码模板,可以直接使用的。

    首先是微信界面菜单栏设计的请求,将下面这个php文件放进随便一个php环境运行一下就可以了,目的是让它发出请求就好了。(订阅号配置url后没有权限,会返回失败

<?php

/* 以下两项可登陆微信公众平台查看 */
$appid = "******************";
$appsecret = "******************";

/* 菜单设计 */
$menu = array(
	'button' => array(
		array('name'=>'菜单一','sub_button'=>array(
                array('type'=>'click', 'name'=>'二级菜单', 'key'=>'13'),
                array('type'=>'view','name'=>'百度','url'=>'www.baidu.com'),
			)
		),
		array('name'=>'菜单二','sub_button'=>array(
            array('type'=>'view','name'=>'卡种查询','url'=>'www.baidu.com'),
			array('type'=>'click', 'name'=>'百度', 'key'=>'21'),
			)
		),
		array('name'=>'菜单三','sub_button'=>array(
			array('type'=>'view', 'name'=>'百度', 'url'=>'www.baidu.com'),
			)
		),
		)
	);
    
/* 发起更新菜单用的curl请求 */
function https_request($url,$data = null)
{
	$curl = curl_init();
	curl_setopt($curl, CURLOPT_URL, $url);
	curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
	if (!empty($data))
	{
		curl_setopt($curl, CURLOPT_POST, 1);
		curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
	}
	curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
	$output = curl_exec($curl);
	curl_close($curl);
	return $output;
}

/* 去除php版本的影响 */
function json_encode_ex($value)
{
    if (version_compare(PHP_VERSION,'5.4.0','<'))
    {
        $str = json_encode($value);
        $str = preg_replace_callback(
            "#\\\u([0-9a-f]{4})#i",
            function($matchs)
            {
                 return iconv('UCS-2BE', 'UTF-8', pack('H4', $matchs[1]));
            },
             $str
            );
        return $str;
    }
    else
    {
        return json_encode($value, JSON_UNESCAPED_UNICODE);
    }
}

/* 发起请求 */
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}";
$result = https_request($url);

$jsoninfo = json_decode($result, true);
$access_token = $jsoninfo["access_token"];
$url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token;
$jsonmenu = json_encode_ex($menu);
$result = https_request($url, $jsonmenu);
var_dump($result);

?>

接下来是前面配置的服务器url地址文件,就是那个index.php:(token要改成自己的

<?php

require "./menu.class.php";                 //引进回复的文件
define("TOKEN", "******");                  //设置token常量,这里是*号,要改成你自己在微信公众号平台设置的token

$wechatObj = new wechatCallbackapiTest();   //实例化wechatCallbackapiTest对象
//$wechatObj->valid();                      //验证消息来自微信服务器第一次使用就行
$wechatObj->responseMsg();                  //处理消息


class wechatCallbackapiTest
{

    /**
    * 接受处理微信服务器发送过来的消息
    */
    public function responseMsg()
    {
        /*获取post数据(XML类型)*/
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

		if(!empty($postStr)){//判断获取到的XML数据是否为空
                
            /* 解析XML数据 */
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            
            /* 获取发信方的用户名 */
            $fromUsername = $postObj->FromUserName;
            
            /* 获取消息类型(event 事件 | text 文本)*/
            $RX_TYPE = trim($postObj->MsgType);
            
            /* 根据 消息类型 进行跳转 */
            switch ($RX_TYPE)
            {
                //点击事件
                case "event":
                    $resultStr = $this->receiveEvent($postObj, $user);
                    break;
                    
                //文本输入事件
                case "text":
                    $resultStr = $this->receiveText($postObj, $user);
                    break;
                    
                //其他
                default:
                    $resultStr = "unknow msg type: ".$RX_TYPE;
                    break;
            }
        }else{
            //XML数据为空,do nothing...
        }
    }
    
    /**
    * 点击事件接口
    */
    protected function receiveEvent($postObj, $user){
        
        /* 获取收发方 */
        $fromUsername = $postObj->FromUserName;     //得到发送方名称
        $toUsername = $postObj->ToUserName;         //得到接收方的名称
        
        /*event事件的类型(subscribe 新用户订阅事件 | CLICK 点击回复请求 | VIEW 界面请求)*/
        $event_type = trim($postObj->Event);

        /* 生成一个menu对象,定义在menu.calss.php文件 */
        $menu=new menu();
        
        /*事件处理*/
        if($event_type == "subscribe"){//新用户订阅事件处理
            $sendData = array(
                "act"           => "asyn_send_adduser" ,
                "bind_openid"   => $fromUsername ,
                "bind_key"      => '147258' ,
            );
            $menu->Welcome_Words($fromUsername,$toUsername);//新用户欢迎词(我封装好的接口,后面会附上)
        }
        else if($event_type == "CLICK")
        {
            switch (trim($postObj->EventKey))//对用户请求的key进行筛选
            {
                case "13":
                    $data="Hi,你好~";
                    $result=$menu->Output_Text_Message($data,$fromUsername,$toUsername);
                    echo $result;
                    break;
                case "21":
                    $data="Hi,你好~";
                    $result=$menu->Output_Text_Message($data,$fromUsername,$toUsername);
                    echo $result;
                    break;
                default :
                    $data = "没有该菜单";	
                    $result=$menu->Output_Text_Message($data,$fromUsername,$toUsername);
                    echo $result;
                    break;
            }
            exit(1);
        }
    }
    
    
    /**
    * 文本消息事件接口
    */
    protected function receiveText($postObj, $user){
        
        /* 获取收发方 */
        $fromUsername = $postObj->FromUserName;     //得到发送方名称
        $toUsername = $postObj->ToUserName;         //得到接收方的名称

        /*获取当前时间*/
        $time = time();
        
        /* 生成一个menu对象,定义在menu.calss.php文件 */
        $menu=new menu();
        
        
        /*消息内容处理*/
        if(is_numeric($keyword))//用户输入了纯数字
        {
            $data="Hi,你输入了数字!";
            $result=$menu->Output_Text_Message($data,$fromUsername,$toUsername);
            echo $result;
        }
        else {//其他情况
            $data="Hi,你输入了其他内容!";
            $result=$menu->Output_Text_Message($data,$fromUsername,$toUsername);
            echo $result;
        }
    }
    
    
    /**
    * 验证消息是否来自微信服务器(入口)
    */
    protected function valid()
    {
        $echoStr = $_GET["echostr"];    //收集get数据(随机字符串)
        if($this->checkSignature()){    //判断checkSignature()自定义函数结果(验证微信服务器)
            echo $echoStr;              //为真则输出结果(随机字符串)
        }
    }

    
    /**
    * 验证消息是否来自微信服务器
    */
    private function checkSignature()
    {       
        $signature = $_GET["signature"];                //微信加密签名
        $timestamp = $_GET["timestamp"];                //时间戳
        $nonce = $_GET["nonce"];                        //随机数         
        $token = TOKEN;                                 //token与上面对应
        $tmpArr = array($token, $timestamp, $nonce);    //组装创建数组
        sort($tmpArr, SORT_STRING);                     //把$tmpArr做字符串处理并排序(升序)
        $tmpStr = implode( $tmpArr );                   //将数组变成字符串
        $tmpStr = sha1( $tmpStr );                      //计算字符串散列   
        if( $tmpStr == $signature ){    //判断是否一致
            return true;                //符合返回真
        }else{
            return false;               //否则返回假
        }
    }
    
}

?>
接下来是我封装好的menu类:

<?php
class menu
{
	/* 文本输出 */
	function Output_Text_Message($data,$fromUsername,$toUsername){
		$time = time();
		$msgType="text";
		$textTpl = "<xml>
					<ToUserName><![CDATA[%s]]></ToUserName>
					<FromUserName><![CDATA[%s]]></FromUserName>
					<CreateTime>%s</CreateTime>
					<MsgType><![CDATA[%s]]></MsgType>
					<Content><![CDATA[%s]]></Content>
					<FuncFlag>0</FuncFlag>
					</xml>";
		$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $data);
        return $resultStr;
	}
    
    /* 新用户关注欢迎词 */
    function Welcome_Words($fromUsername,$toUsername)
    {
        $data = "欢迎关注福建通联支付,点击菜单进入更多功能哦~".$this->bytes_to_emoji(0x1F604);
        $resultStr=$this->Output_Text_Message($data,$fromUsername,$toUsername);
		echo $resultStr;
    }
    
    /* 错误信息提示 */
	function Input_Error($fromUsername,$toUsername)
	{
		$data="输入内容有误,请检查格式,重新输入哈~~~";
		$show=$this->Output_Text_Message($data,$fromUsername,$toUsername);
		return $show;

	}
    
    /* 字节转Emoji表情 */
    function bytes_to_emoji($cp)
    {
        if ($cp > 0x10000){       # 4 bytes
            return chr(0xF0 | (($cp & 0x1C0000) >> 18)).chr(0x80 | (($cp & 0x3F000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else if ($cp > 0x800){   # 3 bytes
            return chr(0xE0 | (($cp & 0xF000) >> 12)).chr(0x80 | (($cp & 0xFC0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else if ($cp > 0x80){    # 2 bytes
            return chr(0xC0 | (($cp & 0x7C0) >> 6)).chr(0x80 | ($cp & 0x3F));
        }else{                    # 1 byte
            return chr($cp);
        }
    }
}
?>
到此,一个完整的微信公众平台就搭建完成啦~


这个只是一个基本的框架,微信公众号还有很多的功能,这里就不一一描述啦,详细的可以看官方的文档,上链接:

微信公众号开发官方文档


有什么错误的还希望大伙儿提出来探讨一下哈~~~

(原创不易,转载请注明出处!)


  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值