2014-12-01 14:24:01 liangyh32 阅读数 1160
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5673 人正在学习 去看看 秦子恒

<?php
//
// 响应用户消息
// 微信公众账号响应给用户的不同消息类型
//

define("TOKEN", "weixin");

$wechatObj = new wechatCallbackapiTest();
if (!isset($_GET['echostr'])) {
 $wechatObj->responseMsg();
}else{
    $wechatObj->valid();
}

class wechatCallbackapiTest
{
    public function valid()
    {
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    private function checkSignature()
    {
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];
        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);

        if($tmpStr == $signature){
            return true;
        }else{
            return false;
        }
    }

    public function responseMsg()
    {
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
        if (!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $RX_TYPE = trim($postObj->MsgType);

            //用户发送的消息类型判断
            switch ($RX_TYPE)
            {
                case "text":
                    $result = $this->receiveText($postObj);
                    break;
                case "image":
                    $result = $this->receiveImage($postObj);
                    break;
                case "voice":
                    $result = $this->receiveVoice($postObj);
                    break;
                case "video":
                    $result = $this->receiveVideo($postObj);
                    break;
                default:
                    $result = "unknow msg type: ".$RX_TYPE;
                    break;
            }
            echo $result;
        }else {
            echo "";
            exit;
        }
    }
   
    private function receiveText($object)
    {
        $keyword = trim($object->Content);

        if($keyword == "文本"){
            //回复文本消息
            $content = "这是个文本消息";
            $result = $this->transmitText($object, $content);
        }
        else if($keyword == "图文" || $keyword == "单图文"){
            //回复单图文消息
            $content = array();
            $content[] = array("Title"=>"单图文标题",
                                "Description"=>"单图文内容",
                                "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg",
                                "Url" =>"http://m.cnblogs.com/?u=txw1958");
            $result = $this->transmitNews($object, $content);
        }
        else if($keyword == "多图文"){
            //回复多图文消息
            $content = array();
            $content[] = array("Title"=>"多图文1标题", "Description"=>"", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
            $content[] = array("Title"=>"多图文2标题", "Description"=>"", "PicUrl"=>"http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
            $content[] = array("Title"=>"多图文3标题", "Description"=>"", "PicUrl"=>"http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
            $result = $this->transmitNews($object, $content);
          
        }
        else if($keyword == "音乐"){
            //回复音乐消息
            $content = array("Title"=>"最炫民族风",
            "Description"=>"歌手:凤凰传奇",
            "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3",
            "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3");
            $result = $this->transmitMusic($object, $content);
        }
       
        return $result;
    }

    private function receiveImage($object)
    {
        //回复图片消息
        $content = array("MediaId"=>$object->MediaId);
        $result = $this->transmitImage($object, $content);;
        return $result;
    }

    private function receiveVoice($object)
    {
        //回复语音消息
        $content = array("MediaId"=>$object->MediaId);
        $result = $this->transmitVoice($object, $content);;
        return $result;
    }

    private function receiveVideo($object)
    {
        //回复视频消息
        $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");
        $result = $this->transmitVideo($object, $content);;
        return $result;
    } 
   
    /*
     * 回复文本消息
     */
    private function transmitText($object, $content)
    {
        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
        return $result;
    }
   
    /*
     * 回复图片消息
     */
    private function transmitImage($object, $imageArray)
    {
        $itemTpl = "<Image>
    <MediaId><![CDATA[%s]]></MediaId>
</Image>";

        $item_str = sprintf($itemTpl, $imageArray['MediaId']);

        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
$item_str
</xml>";

        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }
   
    /*
     * 回复语音消息
     */
    private function transmitVoice($object, $voiceArray)
    {
        $itemTpl = "<Voice>
    <MediaId><![CDATA[%s]]></MediaId>
</Voice>";

        $item_str = sprintf($itemTpl, $voiceArray['MediaId']);

        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
$item_str
</xml>";

        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }
   
    /*
     * 回复视频消息
     */
    private function transmitVideo($object, $videoArray)
    {
        $itemTpl = "<Video>
    <MediaId><![CDATA[%s]]></MediaId>
    <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
    <Title><![CDATA[%s]]></Title>
    <Description><![CDATA[%s]]></Description>
</Video>";

        $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);

        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
$item_str
</xml>";

        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }
   
    /*
     * 回复图文消息
     */
    private function transmitNews($object, $arr_item)
    {
        if(!is_array($arr_item))
            return;

        $itemTpl = "    <item>
        <Title><![CDATA[%s]]></Title>
        <Description><![CDATA[%s]]></Description>
        <PicUrl><![CDATA[%s]]></PicUrl>
        <Url><![CDATA[%s]]></Url>
    </item>
";
        $item_str = "";
        foreach ($arr_item as $item)
            $item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);

        $newsTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
$item_str</Articles>
</xml>";

        $result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
        return $result;
    }
   
    /*
     * 回复音乐消息
     */
    private function transmitMusic($object, $musicArray)
    {
        $itemTpl = "<Music>
    <Title><![CDATA[%s]]></Title>
    <Description><![CDATA[%s]]></Description>
    <MusicUrl><![CDATA[%s]]></MusicUrl>
    <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
</Music>";

        $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);

        $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
$item_str
</xml>";

        $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
        return $result;
    }
}
?>

2018-04-19 08:01:09 anyangjie11 阅读数 2803
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5673 人正在学习 去看看 秦子恒

微信开发自定义回复文本

<?php
namespace Home\Controller;
use Think\Controller;
use LaneWeChat\Core\Curl;

class AutoreplyController extends Controller
{
	private $mp;
	public function _initialize(){
		$mp = getCurrentMp();
		if(empty($mp)){
			$this->error('无使用的公众号',U('mp/index'));
			exit;
		}else{
			$this->mp = $mp;
		}
	}

	public function index(){
         $this->display('replytext');
	}
	//回复文本消息
	public function replytext(){
		$data['content'] = I('content');
		$replyid = M('mp_reply_text')->add($data);
		if($replyid){
		$mp = $this->mp;
		$arr['mp_id'] = $mp['id'];
		$arr['type'] = 'text';
		$arr['keyword'] = I('keyword');
		$arr['reply_id'] = $replyid;

		$ret = M('mp_rule')->add($arr);
		if($ret){
			$this->ajaxReturn(array('msg'=>'添加成功','url'=>U('keyword',['type'=>'text'])));
		}else{
				$this->ajaxReturn(array('msg'=>$ret));
			
		}
		}else{
				$this->ajaxReturn(array('msg'=>$ret));
		}
	}
}

自定义菜单点击文本回复在wechatquest.php中设置为

 public static function eventClick(&$request){
        //获取该分类的信息
        $eventkey = $request['eventkey'];
        $request['content'] = $eventkey;
        return self::text($request);
        // $content = '收到点击菜单事件,您设置的key是' . $eventKey;
        // return ResponsePassive::text($request['fromusername'], $request['tousername'], $content);
    }

2013-12-25 11:33:59 u012275531 阅读数 1940
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5673 人正在学习 去看看 秦子恒
微信自定义菜单接口


简介


PHP 开发者获取使用凭证(如何获取凭证)后,可以使用该凭证对公众账号的自定义菜单进行创建、查询和删除等操作。 自定义菜单接口可实现以下类型按钮:

click(点击事件):用户点击click类型按钮后,微信服务器会通过消息接口(event类型)推送点击事件给开发者,并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值进行消息回复。view(访问网页):用户点击view类型按钮后,会直接跳转到开发者指定的url中。


创建自定义菜单后,由于微信客户端缓存,需要24小时微信客户端才会展现出来。建议测试时可以尝试取消关注公众账号后,再次关注,则可以看到创建后的效果。 (PS:T不错的PHP Q扣峮:276167802,验证:csl)


菜单创建


接口说明
通过POST一个特定结构体,实现在微信客户端创建自定义菜单。


请求说明
http请求方式:POST
https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN


请求示例:

{
     "button":[
     {
          "type":"click",
          "name":"今日歌曲",
          "key":"V1001_TODAY_MUSIC"
      },
      {
           "type":"view",
           "name":"歌手简介",
           "url":"http://www.tsingyuan.cn/"
      },
      {
           "name":"菜单",
           "sub_button":[
            {
               "type":"click",
               "name":"hello word",
               "key":"V1001_HELLO_WORLD"
            },
            {
               "type":"click",
               "name":"赞一下我们",
               "key":"V1001_GOOD"
            }]
       }]
 }

创建后效果:



参数说明
参数 是否必须 说明
button 按钮数组,按钮个数应为2~3个
sub_button 子按钮数组,按钮个数应为2~5个
type 按钮类型,目前有click类型
name 按钮描述,既按钮名字,不超过16个字节,子菜单不超过40个字节

key 类型为click必须按钮KEY值,用于消息接口(event类型)推送,不超过128字节


返回说明
正确的Json返回结果:
{"errcode":0,"errmsg":"ok"}


错误的Json返回结果
{"errcode":40018,"errmsg":"invalid button name size"}


统一返回码说明
菜单查询


接口说明
查询当前使用的自定义菜单结构。
请求说明
http请求方式:GET
https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN


返回说明

//对应创建接口,正确的Json返回结果:
{"menu":{"button":[{"type":"click","name":"今日歌曲","key":"V1001_TODAY_MUSIC","sub_button":[]},{"type":"click","name":"歌手简介","key":"V1001_TODAY_SINGER","sub_button":[]},{"name":"菜单","sub_button":[{"type":"click","name":"hello word","key":"V1001_HELLO_WORLD","sub_button":[]},{"type":"click","name":"赞一下我们","key":"V1001_GOOD","sub_button":[]}]}]}}

统一返回码说明


菜单删除


接口说明
取消当前使用的自定义菜单。
请求说明
http请求方式:GET
https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN
返回说明
对应创建接口,正确的Json返回结果:

{"errcode":0,"errmsg":"ok"}


以上是本文关于PHP 微信自定义菜单接口的详解,希望本文对广大php开发者有所帮助,感谢阅读本文。

2016-09-28 12:04:10 lixianseng 阅读数 2642
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5673 人正在学习 去看看 秦子恒

    首先访问微信公众平台:mp.weixin.qq.com 。我们所使用的是订阅号所以能开发的功能仅限于自动回复,自定义菜单,群发功能等等。  

先去开发里面的基本配置点击开启,启用第三方。然后去开发者工具申请一个微信公众平台接口测试账号。这个账号有着所有接口的使用权。

   第一步我们先进行接口信息配置,去消息接口使用指南文档,找到开始开发里面的接入指南找到检验signature的PHP示例代码下载下来,

下载下来的文件里只有一个PHP文件,将这个文件放入服务器里。

   第二步验证服务器地址的有效性,我们先跳过验证,所以在文件的checkSignature方法中第二个if判断前加上return true;我们可以先进行一下测试,访问服务器的这个文件 ,后面加个参数,看是否能够输出 。

   第三步我们返回到接口配置这来,点击编辑 将url替换成你服务器验证文件的地址,Token自己可以随便写一个,然后打开验证文件,文件中有一行代码 defina(“TOKEN”,“XXXXX”);这个token所对应的值要与接口配置的token对应。url 和 token 都填好之后点击提交会提示配置成功。

   简单的一个配置就完成了 。 接下来我们看看微信开发的自动回复,先让我们了解一个消息回复的流程,当我们使用微信客户端的访问公众号的时候,我们可以给公众号发送一个消息,接受我们消息的便是微信服务器。当微信服务器发现我们已经绑定了第三方应用,也就是我们的服务器时,他会调用我们的php文件,执行我们的代码,我们的服务器将要回复的内容返回给微信服务器,然后微信服务器在帮我们把消息显示到客服端。

   第一步在验证文件中找到responseMsg方法 : 方法中刚开始就是定义一些参数获取值等,我们在关注的我们申请的测试号中发送一条文字消息 ,会自动回复 Welcome to wechat word ,将方法中的$contentStr 内容修改为hello 那么这个测试号自动回复的文字便成为了hello。我们发送给公众号消息,微信进行接收,然后再把自动回复的信息,组成xml文件,然后告诉微信,微信在将其展示出来。这就是一个简单的文字信息自动回复。

   在这个自动回复方法中,有一行代码 $msgType = "text" ,text就意味着这是一个文本消息的自动回复 ,有很多比如回复图片消息了,回复视频消息了,回复语音消息了,等等都可以, 并且每一个回复 都会对应着一个xml文件,并不是所有回复都使用的一个xml。

   自动回复消息了解的差不多了,我们来看看创建自定义菜单吧 。

   第一步得先获取一个调用接口的凭证,我们先来新建一个php文件,获取凭证使用的get请求,复制调用接口凭证文档的接口调用请求里的地址,然后放到我们新建的php文件中,在这个文件中我们首先得定义两个常量 ,第一个:define("APPID","XXXXXX"); 第二个:define("APPSECRET","XXXXXX");  他们所对应的值需要我们打开公众管理平台便能够找到;然后将复制的url里面的APPID和APPSECRET进行一个替换,然后我们输出这个url,则获取到一个访问地址,在将这个访问地址访问一下便得到了很多内容,其中一个为access_token,我们所需的
凭证,还有一个expires_in,这个是过期时间。这个内容是一个json数据 ,我们将它用json_decode(),转换为数组形式。然后从数组中获取出来access_token。

   第二步我们在创建一个页面,将获取凭证的页面使用include引入到这个新建的页面中,并且把获取凭证文件中所做的包到一个方法中,使之容易调用。然后我们在新建的页面调用获取凭证界面的方法来获取到access_token。

   第三步打开自定义菜单创建文档,看到接口调用请求说明,是POST请求 ,然后把这个地址复制到我们新建的那个页面中,并定义一个二维数组,将文档中的内容复制进去,然后再定义请求类型为post ,然后进行请求, 如果请求报错了,那么会爆一个 errcode:40018 errms 的错误  成功了则会爆一个 errcode:0,errmsg:OK; 

  第四部将公众号取消关注,然后在进行关注,我们就可以看到公众号的菜单进行了变化。

  那么自定义菜单便完成了。
 
2015-03-03 12:38:21 afanxingzhou 阅读数 4071
  • 微信公众号开发5-自定义菜单-微信开发php

    微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台开发》视频教程的第5部。详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131

    5673 人正在学习 去看看 秦子恒

1.微信公众平台开发必备的一个基础功能是关键词回复。但有时候我们的微信公众号的需要关键词回复的模块比较多时,例如“默认情况下的关键词回复,查询天气时的关键词回复,或者成语接龙等文字游戏的关键词回复”,模块多时不可避免的会出现关键词冲突的问题。
2.在每天搜集公众号案例的时候发现以下几个公众号的情况:
案例一:
默认输入“1”:

默认输入1

点击底部菜单“孕妈菜单”的后再输入1:

点击菜单输入1
案例二:
聊天机器人中的各种文字游戏:

聊天机器人

在这两个案例中,仔细分析都是通过“点击菜单”进入不同的响应事件的。

在“1号店”中,默认连接“查询商品数据库A”,在点击了菜单后进入孕妈数据库B/孕妈响应事件;

在“Autism”中,也是通过点击菜单进入不同数据库/响应事件。
前者以“10分钟无应答”断开菜单事件,后者以“退出关键词”断开菜单事件。
流程图
//=============背景交代完毕,擂主登台============
这里采用连接数据库记录操作的方法解决:

首先在数据库中创建表:
id,openid(用户的身份标识),dianji(用户当前操作),time(时间)
caozuo表

在我的微信公众号中以相同关键词“济源”为例。默认输入“济源”返回“山水之城…”的消息,点击“查天气”菜单后,输入“济源”返回济源当前天气消息。

代码实现
流程图

用户是否点击,输入文本前的判断代码:

include './conn/conn.php';
        mysql_set_charset('utf8');
        $rs_caozuo=mysql_query("SELECT dianji,time FROM caozuo WHERE openid =  '{$object->FromUserName}' ORDER BY id DESC LIMIT 0 ,1",$link);//只查询最近一条记录
        $info_caozuo=mysql_fetch_array($rs_caozuo);
        $biaoji = $info_caozuo['dianji'];

如果没有查询到,

if($biaoji==false or $biaoji=='0')

如果查询到dianji=tianqi,执行天气查询事件

else if($biaoji=="tianqi")

点击“天气”菜单事件的代码:

 case "tianqi":
                        include './conn/conn.php';
                        mysql_set_charset('utf8');
                        $time=date("Y-m-d H:i:s");
                        $rs=mysql_query("INSERT INTO `caozuo`(`openid`, `dianji`, `time`) VALUES ('{$object->FromUserName}','tianqi','{$time}')",$link);
                        $content = "请输入您需要查询的城市,可以语音输入哦~\n\nTips:输入“退出”才可以使用其它功能。";

用户第一次点击,执行插入语句。
在天气查询响应消息事件中放入“退出”关键词操作,更新dianji=’0 ‘

case "退出":
                            $time=date("Y-m-d H:i:s");
                            $rs_tuichu=mysql_query("update `caozuo` set `dianji`='0', `time`='{$time}' where openid='{$object->FromUserName}'",$link);
                            $content ="已经退出,请查询其它内容。";
                            break;

大功告成!
还有一些使用缓存的方法,加入session对话的方法,全局变量的方法但操作麻烦,有的在网页中可用,到了微信类中就不行。所以采用数据库的方式,靠谱。

最终的效果如图:
输入“济源”,点击“查天气”菜单

效果
输入“退出”

效果2

2016-11-10 16:31:08更新:
公众号由于后期使用,以上代码已失效。
附数据表资源:http://download.csdn.net/detail/afanxingzhou/9679126

代码资源:http://download.csdn.net/detail/afanxingzhou/8796933

没有更多推荐了,返回首页