精华内容
下载资源
问答
  • 主要为大家详细介绍了php微信公众号开发之图片回复,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了php微信公众号开发第四课,php实现简单微信文本通讯,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 网盘地址 微信公众平台开发视频教程,还附有相关配套php代码,api接口,自定义菜单,等等
  • 查取会员卡用户信息接口,创建会员卡接口,会员卡人工冲积分接口,微信创建区分不同的来源渠道的扫码会员卡接口,微信接口创建菜单接口
  • 微信公众号中,对接录音开发接口,开发适用demo;我们经常适用的方法,附带代码
  • 此项目是微信公众号批量自动化爬虫的核心实现, 面向开发者开源, 可以当做go语言包引入到自己项目中, 完整产品必须二次开发实现,QQ交流群: 563954381 微信的防作弊一直在不断更新完善,过于频繁的抓取可能导致微信...
  • 微信公众平台开发微信用户开发管理是子恒老师...详细讲解了用php开发微信,对微信公众平台中的粉丝用户管理开发。内容包含微信公众平台用户分组,获取微信用户列表,查询用户详情等等。欢迎反馈,微信/QQ:68183131
  • 微信公众号php实现微信公众号回复消息发布时间:2019-02-28 16:32:52作者:wangjian浏览量:999点赞量:0一:回复文本消息当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,...

    您现在的位置是:网站首页>>微信>>微信公众号

    php实现微信公众号回复消息

    发布时间:2019-02-28 16:32:52作者:wangjian浏览量:999点赞量:0

    一:回复文本消息

    当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复,这里主要介绍下文本消息回复,图片消息回复,图文消息回复

    一:文本消息回复

    发送文本消息必须要为如下这种xml格式:

    12345678

    参数说明:

    参数是否必须描述

    ToUserName是接收方帐号(收到的OpenID)

    FromUserName是开发者微信号

    CreateTime是消息创建时间 (整型)

    MsgType是text

    Content是回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)

    例://获取微信传递过来的值

    $tmpXML = file_get_contents('php://input'); //读取没有处理过的原始数据

    //解析xml ,对象,数组

    $obj = new \SimpleXMLElement($tmpXML); //php 内置类,用来解析xml转成对象,创建xml

    foreach ($obj as $key => $v) {

    $this->result[$key] = strval($v); //把变量转换成字符串

    }

    $message = '终于等到你,还好我没放弃!!!';

    $data = '

    result['FromUserName'].']]>

    result['ToUserName'].']]>

    '.time().'

    ';

    echo $data;

    exit();

    二:图片消息回复

    图片消息回复xml格式如下:

    12345678

    参数说明

    参数是否必须说明

    ToUserName是接收方帐号(收到的OpenID)

    FromUserName是开发者微信号

    CreateTime是消息创建时间 (整型)

    MsgType是image

    MediaId是通过素材管理中的接口上传多媒体文件,得到的id。素材管理教程可以参考微信公众号文档,这里不多说明

    例://获取微信传递过来的值

    $tmpXML = file_get_contents('php://input'); //读取没有处理过的原始数据

    //解析xml ,对象,数组

    $obj = new \SimpleXMLElement($tmpXML); //php 内置类,用来解析xml转成对象,创建xml

    foreach ($obj as $key => $v) {

    $this->result[$key] = strval($v); //把变量转换成字符串

    }

    $media_id = 'b13CgKi0FlGgbD0ngc5i95FecOGRnFTVxZv_5hs8QqYRfd8xn9ZL0zlVcQO0REcD';

    $data = '

    result['FromUserName'].']]>

    result['ToUserName'].']]>

    '.time().'

    ';

    echo $data;

    exit;

    三:图文消息回复

    图文消息回复xml格式如下:

    12345678

    1

    参数说明:

    参数是否必须说明

    ToUserName是接收方帐号(收到的OpenID)

    FromUserName是开发者微信号

    CreateTime是消息创建时间 (整型)

    MsgType是news

    ArticleCount是图文消息个数;当用户发送文本、图片、视频、图文、地理位置这五种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息

    Articles是图文消息信息,注意,如果图文数超过限制,则将只发限制内的条数

    Title是图文消息标题

    Description是图文消息描述

    PicUrl是图片链接,支持JPG、PNG格式,较好的效果为大图360*200,小图200*200

    Url是点击图文消息跳转链接

    例://获取微信传递过来的值

    $tmpXML = file_get_contents('php://input'); //读取没有处理过的原始数据

    //解析xml ,对象,数组

    $obj = new \SimpleXMLElement($tmpXML); //php 内置类,用来解析xml转成对象,创建xml

    foreach ($obj as $key => $v) {

    $this->result[$key] = strval($v); //把变量转换成字符串

    }

    //获取信息

    $article = SkillArticle::find()

    ->alias('article')

    ->select(['article.*','details.img as detail_img'])

    ->join('LEFT JOIN','skill_details as details','article.details_id = details.id')

    ->andWhere(['article.is_deleted'=>1])

    ->orderBy(['article.id'=>SORT_DESC])

    ->limit(1)

    ->asArray()

    ->all();

    $info = [];

    foreach ($article as $model){

    if(!empty($model['detail_img'])){

    $picurl= 'https://api.wj0511.com/static'.$model['detail_img'];

    }else{

    $picurl = '/images/01.jpg';

    }

    $info[] = [

    'title'=>$model['title'],

    'description'=>mb_substr(strip_tags($model['content']),0,60,"UTF-8").'...',

    'picurl'=>$picurl,

    'url'=>'https://www.wj0511.com/site/detail.html?id='.$model['id'],

    ];

    }

    $data = '

    result['FromUserName'].']]>

    result['ToUserName'].']]>

    '.time().'

    '.count($info).'

    ';

    foreach ($info as $value){

    $data .= '

    ';

    }

    $data .= '

    ';

    Yii::error($data);

    echo $data;

    exit;

    272a2ff497ff398701eef161070cd122.png

    0

    +1

    展开全文
  • 微信公众号网页开发

    2021-06-11 06:14:18
    基本配置1.设置—公众号设置—功能设置—配置JS接口安全域名安全域名配置规则如下2.开发—基本配置开发者密码第一次使用需要重新设置记录 开发者ID(AppID) 开发者密码(AppSecret)后面会用到3....微信公众号-开发-接...

    基本配置

    1.设置—公众号设置—功能设置—配置JS接口安全域名

    bVby1Gs?w=553&h=242

    安全域名配置规则如下

    bVby1FR?w=822&h=585

    2.开发—基本配置

    bVby1Gj?w=554&h=232

    开发者密码第一次使用需要重新设置

    记录 开发者ID(AppID) 开发者密码(AppSecret)后面会用到

    3.IP白名单配置

    推荐填写当前本地开发IP地址和服务器IP地址

    本地开发地址获取方式

    bVby1JK?w=795&h=327

    服务器IP地址(根据自己的服务器Ip地址自行填写)

    多个IP地址填写用回车隔开

    4重要的一步

    在:微信公众号-开发-接口权限查看想要调用的开发接口是否可用

    如果有相关接口权限无法开启,推荐使用:微信公众平台-开发-开发者工具-公众平台测试帐号开发

    开始开发

    1.引入JS文件

    2通过config接口注入权限验证配置(最重要的一步)

    wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: '', // 必填,公众号的唯一标识

    timestamp: , // 必填,生成签名的时间戳

    nonceStr: '', // 必填,生成签名的随机串

    signature: '',// 必填,签名

    jsApiList: [] // 必填,需要使用的JS接口列表

    });

    appID(前面在微信公众号基本配置中已经拿到了)

    jsApiList:['uploadImage','updateAppMessageShareData'] (例:上传图片接口,和自定义分享接口)

    签名算法(微信官方提供)

    jsapi_ticket

    生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。

    参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):https://developers.weixin.qq....

    用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket):https://api.weixin.qq.com/cgi...

    2.1签名获取拆解

    第一步GET请求access_token

    grant_type是获取access_token填写client_credential

    appid是第三方用户唯一凭证

    secret是第三方用户唯一凭证密钥,即appsecret**

    appid 和 secret 在前面的基本配置中其实都已经拿到。但是由于开发者密码(AppSecret)是校验公众号开发者身份的密码,具有极高的安全性。不能直接暴露在前端代码中,所以access_token的请求需在后端完成,这里签名的生成过程都在后端完成。

    当前以node搭建后端服务

    //获取到access_token示例

    var url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`;

    request(url, function (error, response, body) {

    if (!error && response.statusCode == 200) {

    console.log("access_token值" +JSON.parse(body).access_token)

    }

    });

    第二步GET请求jsapi_ticket

    jsapi_ticket的有效期为7200秒(不必反复请求)

    https://api.weixin.qq.com/cgi...

    用第一步获取到的access_token的值进行请求

    //

    var url = `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`

    request(url, function (error, response, body) {

    if (!error && response.statusCode == 200) {

    console.log("jsapi_ticket值" + JSON.parse(body).ticket);

    }

    });

    第三步生成算法签名

    const timestamp = parseInt(Date.now() / 1000) //生成签名的时间戳

    const nonceStr = Math.random().toString(36).substr(2, 15) //生成签名的随机串

    let jsapi_ticket //在第二步生成

    let url//签名用的url必须是调用JS接口页面的完整URL(前端请求服务端接口带入)

    const sha1 = require('sha1')//这里需要引入一个插件npm install sha1

    router.get('/', (req, res, next) => {

    const url = decodeURIComponent(req.query.url)//这里的url采用前端加密,后端解密的形式获取

    const timestamp = parseInt(Date.now() / 1000)

    const nonceStr = Math.random().toString(36).substr(2, 15)

    let jsapi_ticket = "在第二步拿到了"

    const params = {

    nonceStr,

    jsapi_ticket,

    timestamp,

    url

    }

    const string = Object.keys(params).sort().map(key => `${key.toLowerCase()}=${params[key]}`).join('&')

    const signature = sha1(string)//生成的签名

    res.status(200).json({//将参数返回给前端

    timestamp,

    signature,

    nonceStr

    });

    })

    module.exports = router;

    3前端静态页面实际调用

    Document

    分享页面

    function wxFN(){

    $.ajax({

    type: "get",

    url: `http://*************/api/wx?url=${encodeURIComponent(location.href.split('#')[0])}`,

    success: function(data) {

    console.log(data);

    wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: data.appId, // 必填,公众号的唯一标识

    timestamp: data.timestamp, // 必填,生成签名的时间戳

    nonceStr: data.nonceStr, // 必填,生成签名的随机串

    signature: data.signature, // 必填,签名

    jsApiList: ['updateAppMessageShareData'] // 必填,需要使用的JS接口列表

    });

    }

    });

    }

    wxFN()

    wx.ready(function() { //需在用户可能点击分享按钮前就先调用

    wx.updateAppMessageShareData({

    title: '', // 分享标题

    desc: '', // 分享描述

    link: '', // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致

    imgUrl: '', // 分享图标

    success: function() {

    alert("成功")

    // 设置成功

    }

    })

    });

    wx.error(function(res) {

    console.log('err', res)

    });

    4常见错误及解决方法(微信提供)

    调用config 接口的时候传入参数 debug: true 可以开启debug模式,页面会alert出错误信息。以下为常见错误及解决方法:

    invalid url domain当前页面所在域名与使用的appid没有绑定,请确认正确填写绑定的域名,仅支持80(http)和443(https)两个端口,因此不需要填写端口号(一个appid可以绑定三个有效域名,见 ]目录1.1.1)。

    invalid signature签名错误。建议按如下顺序检查:

    确认config中nonceStr(js中驼峰标准大写S), timestamp与用以签名中的对应noncestr, timestamp一致。

    确认url是页面完整的url(请在当前页面alert(location.href.split('#')[0])确认),包括'http(s)😕/'部分,以及'?'后面的GET参数部分,但不包括'#'hash后面的部分。

    确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

    确保一定缓存access_token和jsapi_ticket。

    确保你获取用来签名的url是动态获取的,动态页面可参见实例代码中php的实现方式。如果是html的静态页面在前端通过ajax将url传到后台签名,前端需要用js获取当前页面除去'#'hash部分的链接(可用location.href.split('#')[0]获取,而且需要encodeURIComponent),因为页面一旦分享,微信客户端会在你的链接末尾加入其它参数,如果不是动态获取当前链接,将导致分享后的页面签名失败。

    the permission value is offline verifying这个错误是因为config没有正确执行,或者是调用的JSAPI没有传入config的jsApiList参数中。建议按如下顺序检查:

    确认config正确通过。

    如果是在页面加载好时就调用了JSAPI,则必须写在wx.ready的回调中。

    确认config的jsApiList参数包含了这个JSAPI。

    permission denied该公众号没有权限使用这个JSAPI,或者是调用的JSAPI没有传入config的jsApiList参数中(部分接口需要认证之后才能使用)。

    function not exist当前客户端版本不支持该接口,请升级到新版体验。

    为什么6.0.1版本config:ok,但是6.0.2版本之后不ok(因为6.0.2版本之前没有做权限验证,所以config都是ok,但这并不意味着你config中的签名是OK的,请在6.0.2检验是否生成正确的签名以保证config在高版本中也ok。)

    在iOS和Android都无法分享(请确认公众号已经认证,只有认证的公众号才具有分享相关接口权限,如果确实已经认证,则要检查监听接口是否在wx.ready回调函数中触发)

    服务上线之后无法获取jsapi_ticket,自己测试时没问题。(因为access_token和jsapi_ticket必须要在自己的服务器缓存,否则上线后会触发频率限制。请确保一定对token和ticket做缓存以减少2次服务器请求,不仅可以避免触发频率限制,还加快你们自己的服务速度。目前为了方便测试提供了1w的获取量,超过阀值后,服务将不再可用,请确保在服务上线前一定全局缓存access_token和jsapi_ticket,两者有效期均为7200秒,否则一旦上线触发频率限制,服务将不再可用)。

    uploadImage怎么传多图(目前只支持一次上传一张,多张图片需等前一张图片上传之后再调用该接口)

    没法对本地选择的图片进行预览(chooseImage接口本身就支持预览,不需要额外支持)

    通过a链接(例如先通过微信授权登录)跳转到b链接,invalid signature签名失败(后台生成签名的链接为使用jssdk的当前链接,也就是跳转后的b链接,请不要用微信登录的授权链接进行签名计算,后台签名的url一定是使用jssdk的当前页面的完整url除去'#'部分)

    出现config:fail错误(这是由于传入的config参数不全导致,请确保传入正确的appId、timestamp、nonceStr、signature和需要使用的jsApiList)

    如何把jsapi上传到微信的多媒体资源下载到自己的服务器(请参见文档中uploadVoice和uploadImage接口的备注说明)

    Android通过jssdk上传到微信服务器,第三方再从微信下载到自己的服务器,会出现杂音(微信团队已经修复此问题,目前后台已优化上线)

    绑定父级域名,是否其子域名也是可用的(是的,合法的子域名在绑定父域名之后是完全支持的)

    在iOS微信6.1版本中,分享的图片外链不显示,只能显示公众号页面内链的图片或者微信服务器的图片,已在6.2中修复

    是否需要对低版本自己做兼容(jssdk都是兼容低版本的,不需要第三方自己额外做更多工作,但有的接口是6.0.2新引入的,只有新版才可调用)

    该公众号支付签名无效,无法发起该笔交易(请确保你使用的jweixin.js是官方线上版本,不仅可以减少用户流量,还有可能对某些bug进行修复,拷贝到第三方服务器中使用,官方将不对其出现的任何问题提供保障,具体支付签名算法可参考 JSSDK微信支付一栏)

    目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题已在Android6.2中修复

    uploadImage在chooseImage的回调中有时候Android会不执行,Android6.2会解决此问题,若需支持低版本可以把调用uploadImage放在setTimeout中延迟100ms解决

    require subscribe错误说明你没有订阅该测试号,该错误仅测试号会出现

    getLocation返回的坐标在openLocation有偏差,因为getLocation返回的是gps坐标,openLocation打开的腾讯地图为火星坐标,需要第三方自己做转换,6.2版本开始已经支持直接获取火星坐标

    查看公众号(未添加): "menuItem:addContact"不显示,目前仅有从公众号传播出去的链接才能显示,来源必须是公众号

    ICP备案数据同步有一天延迟,所以请在第二日绑定

    展开全文
  • 我们可以通过微信端给我们发送来的xml来判断用户发送消息的类型,比如文本,图片,音频等等,具体获取看代码$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //获取POST数据$postObj = simplexml_load_...

    好了,上一篇已经介绍到了如何成为一个微信开发者,并且简单介绍了如何获取和发送简单的文本信息,这次就来介绍一下其他类型数据的接收和发送方式。

    我们可以通过微信端给我们发送来的xml来判断用户发送消息的类型,比如文本,图片,音频等等,具体获取看代码

    $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //获取POST数据

    $postObj = simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);//这就是微信发来的xml

    $fromUsername = $postObj->FromUserName; //获取发送方帐号(OpenID)

    $toUsername = $postObj->ToUserName; //获取接收方账号

    $keyword = trim($postObj->Content); //获取消息内容

    $masType = $postObj->MsgType;//获取消息类型

    $time = time(); //获取当前时间戳

    可以看到,获取到的xml中,MsgType就是用户发送数据的类型,分别有 'text'(文本),'image'(图片),location(位置),voice(音频),video(视频)等。我们就做一个简单的根据用户发送类型来返回相应数据的demo。

    首先用switch case来区分不同的类型,这个函数不知道的自己百度,而后对应来编写代码

    1,文字

    我们就做成简单的 “你发送的是:”格式的demo。先定义回复文本格式的xml模板,而后把刚获取的用户文字和我们需要的内容合并,最后通过 resultStr() 函数来格式化消息模板。函数用法自行百度

    //返回消息模板

    $textTpl = "%s

    0";

    switch ($masType) {

    case 'text'://文字

    $msgType = "text"; //消息类型

    $contentStr = '你发送的是:'.$keyword;

    $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);

    echo $resultStr;

    break;

    这样就会得到一个这样的回复。

    625bd30b6c964dac7714536694f60268.png

    image.png

    2.图片

    同样的,我们还是做一个把用户发来的图片再发回给他的demo。用户在像我们的公众号发送图片的时候,微信平台会在保存图片的同时,给这张图片一个唯一的URL以及mediaId,这个URL在浏览器直接访问就是你的那张图片。开发者需要在服务器获取该图片的mediaId,而后再按照格式发送给微信方,微信就会返还对应这个mediaId的图片给用户。

    $picUrl = $postObj->PicUrl;//图片的链接

    $mediaId = $postObj->MediaId;//图片消息媒体id

    $msgType = "image";

    $replyXml = "%s";

    echo sprintf($replyXml,$postObj->FromUserName,$postObj->ToUserName,time(),$msgType,$mediaId);

    86e57e5db0a34c617967288ed85e9950.png

    image.png

    另外,如果你想发送指定的图片给客户,那么你需要先在开发者端把图片发送给微信方,而后获取这个图片的mediaId,你可以选择发送临时素材(保存三天)或者永久素材,具体操作请看微信官方文档。

    3.图文

    我们自己关注的公众号,给我们发送最多的消息应该就是图文消息了,就是类似这样的

    a1d9527db61b4f50db9b357431687707.png

    image.png

    大家肯定都知道,这样的消息,在微信公众平台,点点敲敲的就可以发送了,但是这完全没有开发者的代码逻辑在内,也无法完全控制,所以我们要用代码来实现这个功能。

    首先我们定义一个二维数组,其中的参数名称如代码所示

    $newsArr = array(

    array(

    "Title"=>"本世纪最像王昊的男人!",

    "Description"=>"究竟是为何和王昊长得如此相像?",

    "PicUrl"=>"http://5b0988e595225.cdn.sohucs.com/images/20171019/aab0f430638b4b1f87e48d19054b7b60.jpeg",

    "Url"=>"http://www.wanghao-home.club"

    ),

    array(

    "Title"=>"艳照门祖师爷再现江湖!",

    "Description"=>"究竟是电脑坏了还是存心所为…",

    "PicUrl"=>"http://g.hiphotos.baidu.com/baike/pic/item/060828381f30e92496694c1044086e061c95f7c6.jpg",

    "Url"=>"http://www.wanghao-home.club"

    ),

    array(

    "Title"=>"音乐才子竟拜师?",

    "Description"=>"伯克利音乐才子竟然为何拜师王昊门下?让我们来一探究竟!",

    "PicUrl"=>"http://img01.e23.cn/2017/1003/20171003094603817.jpg",

    "Url"=>"http://www.wanghao-home.club"

    )

    );

    可以看到,这个二维数组中,一级数组一个,二级数组三个,其中的参数也都相同

    Title:文章标题 Description:文章描述 PicUrl:文章图片 Url:点击会跳转的链接

    好了,数组定义完成,我们就要把数组处理成为微信可以接收的xml数据了,这里我给你提供一个方法

    //判断是否为数组类型

    if(!is_array($newsArr))

    {

    return;

    }

    // 判断数组是否为空数组

    if(!$newsArr)

    {

    return;

    }

    $itemStr = "";

    //定义item模板

    $itemXml = "";

    foreach($newsArr as $item)

    {

    $itemStr .= sprintf($itemXml,$item['Title'],$item['Description'],$item['PicUrl'],$item['Url']);

    }

    $replyXml = "%s

    ".count($newsArr)."

    ".$itemStr."";

    echo sprintf($replyXml,$postObj->FromUserName,$postObj->ToUserName,time());

    代码里也没有什么复杂的地方,就是一个循环赋值的过程,最后再格式化返回给微信方,这样我们的用户就会收到这样的一个图文消息

    7109faaedac6641c967ca32c2f9d2b13.png

    image.png

    并且点击对应的内容,就会跳转到 www.wanghao-home.club

    4.用户关注

    用户在关注我们公众号时,公众平台会发送给我们一个xml数据,我们可以获取其中的事件(Event),来判断,而后回复给用户一个欢迎语句

    if($postObj->Event == 'subscribe'){

    $msgType = "text"; //消息类型

    $contentStr = '感谢您关注wellHome!';

    $resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);

    echo $resultStr;

    }

    还有就是,个人开发者的订阅号现在无法进行微信认证,所以无法自定义菜单以及一切琐碎的功能,这点这得是让我心碎啊。

    自定义菜单也很简单,我们只需要准备一个 json 数组,而后根据开发者的 AppID 和 AppSecret ,在公众平台上获取一个Access_token,而后token通过验证,你的数组就可以成为公众号的菜单了。并且微信还提供了多种事件,开发者可以在代码中,通过用户不同事件所发送的值以及菜单中你自己定义的 Key值就可以做对应的操作了。

    这篇文章暂时先介绍这三种回复内容的格式,下一篇再详细介绍其他内容格式,希望会对您有所帮助。

    展开全文
  • 如果读者对微信开发没有一个主观上的认识,那么建议读者先研读微信公众平台开发者文档,然后再阅读本文,效果更佳!另外本文的分章节版本可以在八宝粥的博客找到。20160712-Update:微信开发的完整例子已经整理在...

    本文内容较多,包括微信接入、获取微信用户信息、微信支付、JSSDK配置参数获取等部分。如果读者对微信开发没有一个主观上的认识,那么建议读者先研读微信公众平台开发者文档,然后再阅读本文,效果更佳!另外本文的分章节版本可以在八宝粥的博客找到。20160712-Update:微信开发的完整例子已经整理在Github,欢迎查看: yii2-wechat-demo。

    接入微信

    Yii2后台配置

    1.在app/config/params.php中配置token参数return [     //微信接入     'wechat' =>[         'token' => 'your token',     ], ];

    2.在app/config/main.php中配置路由

    因为接口模块使用的RESTful API,所以需要定义路由规则。'urlManager' => [     'enablePrettyUrl' => true,     'enableStrictParsing' => true,     'showScriptName' => false,     'rules' => [         [             'class' => 'yii\rest\UrlRule',             'controller' => 'wechat',             'extraPatterns' => [                 'GET valid' => 'valid',             ],         ],     ], ],

    3.在app/controllers中新建WechatController<?php  namespace api\controllers; use Yii; use yii\rest\ActiveController; class WechatController extends ActiveController {     public $modelClass = '';     public function actionValid()     {         $echoStr = $_GET["echostr"];         $signature = $_GET["signature"];         $timestamp = $_GET["timestamp"];         $nonce = $_GET["nonce"];         //valid signature , option         if($this->checkSignature($signature,$timestamp,$nonce)){             echo $echoStr;         }     }     private function checkSignature($signature,$timestamp,$nonce)     {         // you must define TOKEN by yourself         $token = Yii::$app->params['wechat']['token'];         if (!$token) {             echo 'TOKEN is not defined!';         } else {             $tmpArr = array($token, $timestamp, $nonce);             // use SORT_STRING rule             sort($tmpArr, SORT_STRING);             $tmpStr = implode( $tmpArr );             $tmpStr = sha1( $tmpStr );             if( $tmpStr == $signature ){                 return true;             }else{                 return false;             }         }     } }

    微信公众号后台配置

    在微信公众号后台配置URL和Token,然后提交验证即可。URL:http://app.demo.com/wechats/valid Token:your token

    获取用户信息

    用户表设计CREATE TABLE `wechat_user` (   `id` int(11) NOT NULL,   `openid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,   `nickname` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '微信昵称',   `sex` tinyint(4) NOT NULL COMMENT '性别',   `headimgurl` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '头像',   `country` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '国家',   `province` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '省份',   `city` varchar(50) COLLATE utf8_unicode_ci NOT NULL COMMENT '城市',   `access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,   `refresh_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,   `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ALTER TABLE `wechat_user`   ADD PRIMARY KEY (`id`);

    获取用户信息的相关接口

    1.用户授权接口:获取access_token、openid等;获取并保存用户资料到数据库public function actionAccesstoken() {     $code = $_GET["code"];     $state = $_GET["state"];     $appid = Yii::$app->params['wechat']['appid'];     $appsecret = Yii::$app->params['wechat']['appsecret'];     $request_url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$appsecret.'&code='.$code.'&grant_type=authorization_code';     //初始化一个curl会话     $ch = curl_init();     curl_setopt($ch, CURLOPT_URL, $request_url);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     $result = curl_exec($ch);     curl_close($ch);     $result = $this->response($result);     //获取token和openid成功,数据解析     $access_token = $result['access_token'];     $refresh_token = $result['refresh_token'];     $openid = $result['openid'];     //请求微信接口,获取用户信息     $userInfo = $this->getUserInfo($access_token,$openid);     $user_check = WechatUser::find()->where(['openid'=>$openid])->one();     if ($user_check) {         //更新用户资料     } else {         //保存用户资料     }     //前端网页的重定向     if ($openid) {         return $this->redirect($state.$openid);     } else {         return $this->redirect($state);     } }

    2.从微信获取用户资料public function getUserInfo($access_token,$openid) {     $request_url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN';     //初始化一个curl会话     $ch = curl_init();     curl_setopt($ch, CURLOPT_URL, $request_url);     curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);     $result = curl_exec($ch);     curl_close($ch);     $result = $this->response($result);     return $result; }

    3.获取用户资料接口public function actionUserinfo() {     if(isset($_REQUEST["openid"])){         $openid = $_REQUEST["openid"];         $user = WechatUser::find()->where(['openid'=>$openid])->one();         if ($user) {             $result['error'] = 0;             $result['msg'] = '获取成功';             $result['user'] = $user;         } else {             $result['error'] = 1;             $result['msg'] = '没有该用户';         }     } else {         $result['error'] = 1;         $result['msg'] = 'openid为空';     }     return $result; }

    微信支付

    1.微信支付接口:打包支付数据public function actionPay(){     if(isset($_REQUEST["uid"])&&isset($_REQUEST["oid"])&&isset($_REQUEST["totalFee"])){         //uid、oid、totalFee         $uid = $_REQUEST["uid"];         $oid = $_REQUEST["oid"];         $totalFee = $_REQUEST["totalFee"];         $timestamp = time();         //微信支付参数         $appid = Yii::$app->params['wechat']['appid'];         $mchid = Yii::$app->params['wechat']['mchid'];         $key = Yii::$app->params['wechat']['key'];         $notifyUrl = Yii::$app->params['wechat']['notifyUrl'];         //支付打包         $wx_pay = new WechatPay($mchid, $appid, $key);         $package = $wx_pay->createJsBizPackage($uid, $totalFee, $oid, $notifyUrl, $timestamp);         $result['error'] = 0;         $result['msg'] = '支付打包成功';         $result['package'] = $package;         return $result;     }else{         $result['error'] = 1;         $result['msg'] = '请求参数错误';     }     return $result; }

    2.接收微信发送的异步支付结果通知public function actionNotify(){     $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];     $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);     //     if ($postObj === false) {         die('parse xml error');     }     if ($postObj->return_code != 'SUCCESS') {         die($postObj->return_msg);     }     if ($postObj->result_code != 'SUCCESS') {         die($postObj->err_code);     }     //微信支付参数     $appid = Yii::$app->params['wechat']['appid'];     $mchid = Yii::$app->params['wechat']['mchid'];     $key = Yii::$app->params['wechat']['key'];     $wx_pay = new WechatPay($mchid, $appid, $key);     //验证签名     $arr = (array)$postObj;     unset($arr['sign']);     if ($wx_pay->getSign($arr, $key) != $postObj->sign) {         die("签名错误");     }     //支付处理正确-判断是否已处理过支付状态     $orders = Order::find()->where(['uid'=>$postObj->openid, 'oid'=>$postObj->out_trade_no, 'status' => 0])->all();     if(count($orders) > 0){         //更新订单状态         foreach ($orders as $order) {             //更新订单             $order['status'] = 1;             $order->update();         }         return '';     } else {         //订单状态已更新,直接返回         return '';     } }

    3.微信支付类 WechatPay.php<?php  namespace api\sdk; use Yii; class WechatPay {     protected $mchid;     protected $appid;     protected $key;     public function __construct($mchid, $appid, $key){         $this->mchid = $mchid;         $this->appid = $appid;         $this->key = $key;     }     public function createJsBizPackage($openid, $totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp){         $config = array(             'mch_id' => $this->mchid,             'appid' => $this->appid,             'key' => $this->key,         );         $unified = array(             'appid' => $config['appid'],             'attach' => '支付',             'body' => $orderName,             'mch_id' => $config['mch_id'],             'nonce_str' => self::createNonceStr(),             'notify_url' => $notifyUrl,             'openid' => $openid,             'out_trade_no' => $outTradeNo,             'spbill_create_ip' => '127.0.0.1',             'total_fee' => intval($totalFee * 100),             'trade_type' => 'JSAPI',         );         $unified['sign'] = self::getSign($unified, $config['key']);         $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified));         $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA);         if ($unifiedOrder === false) {             die('parse xml error');         }         if ($unifiedOrder->return_code != 'SUCCESS') {             die($unifiedOrder->return_msg);         }         if ($unifiedOrder->result_code != 'SUCCESS') {             die($unifiedOrder->err_code);         }         $arr = array(             "appId" => $config['appid'],             "timeStamp" => $timestamp,             "nonceStr" => self::createNonceStr(),             "package" => "prepay_id=" . $unifiedOrder->prepay_id,             "signType" => 'MD5',         );         $arr['paySign'] = self::getSign($arr, $config['key']);         return $arr;     }     public static function curlGet($url = '', $options = array()){         $ch = curl_init($url);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($ch, CURLOPT_TIMEOUT, 30);         if (!empty($options)) {             curl_setopt_array($ch, $options);         }         //https请求 不验证证书和host         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);         $data = curl_exec($ch);         curl_close($ch);         return $data;     }     public static function curlPost($url = '', $postData = '', $options = array()){         if (is_array($postData)) {             $postData = http_build_query($postData);         }         $ch = curl_init();         curl_setopt($ch, CURLOPT_URL, $url);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($ch, CURLOPT_POST, 1);         curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);         curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数         if (!empty($options)) {             curl_setopt_array($ch, $options);         }         //https请求 不验证证书和host         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);         $data = curl_exec($ch);         curl_close($ch);         return $data;     }     public static function createNonceStr($length = 16){         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';         $str = '';         for ($i = 0; $i";         foreach ($arr as $key => $val){             if (is_numeric($val)) {                 $xml .= "" . $val . "" . $key . ">";             } else {                 $xml .= "" . $key . ">";             }         }         $xml .= "";         return $xml;     }     public static function getSign($params, $key){         ksort($params, SORT_STRING);         $unSignParaString = self::formatQueryParaMap($params, false);         $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));         return $signStr;     }     protected static function formatQueryParaMap($paraMap, $urlEncode = false){         $buff = "";         ksort($paraMap);         foreach ($paraMap as $k => $v){             if (null != $v && "null" != $v) {                 if ($urlEncode) {                     $v = urlencode($v);                 }                 $buff .= $k . "=" . $v . "&";             }         }         $reqPar = '';         if (strlen($buff)>0) {             $reqPar = substr($buff, 0, strlen($buff) - 1);         }         return $reqPar;     } }

    获取JS-SDK的config参数

    根据微信公众平台开发者文档:所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用,目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题会在Android6.2中修复)。

    即:wx.config({     debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。     appId: '', // 必填,公众号的唯一标识     timestamp: , // 必填,生成签名的时间戳     nonceStr: '', // 必填,生成签名的随机串     signature: '',// 必填,签名,见附录1     jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2 });

    1.微信支付类 WechatPay.php<?php  namespace api\sdk; use Yii; class WechatPay {     public function getSignPackage($url) {         $jsapiTicket = self::getJsApiTicket();         $timestamp = time();         $nonceStr = self::createNonceStr();         // 这里参数的顺序要按照 key 值 ASCII 码升序排序         $string = "jsapi_ticket=".$jsapiTicket."&noncestr=".$nonceStr."&timestamp=".$timestamp."&url=".$url;         $signature = sha1($string);         $signPackage = array(             "appId"     => $this->appid,             "nonceStr"  => $nonceStr,             "timestamp" => $timestamp,             "url"       => $url,             "signature" => $signature,             "rawString" => $string         );         return $signPackage;     }     public static function getJsApiTicket() {         //使用Redis缓存 jsapi_ticket         $redis = Yii::$app->redis;         $redis_ticket = $redis->get('wechat:jsapi_ticket');         if ($redis_ticket) {             $ticket = $redis_ticket;         } else {             $accessToken = self::getAccessToken();             $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=".$accessToken;             $res = json_decode(self::curlGet($url));             $ticket = $res->ticket;             if ($ticket) {                 $redis->set('wechat:jsapi_ticket', $ticket);                 $redis->expire('wechat:jsapi_ticket', 7000);             }         }         return $ticket;     }     public static function getAccessToken() {         //使用Redis缓存 access_token         $redis = Yii::$app->redis;         $redis_token = $redis->get('wechat:access_token');         if ($redis_token) {             $access_token = $redis_token;         } else {             $appid = Yii::$app->params['wechat']['appid'];             $appsecret = Yii::$app->params['wechat']['appsecret'];             $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret;             $res = json_decode(self::curlGet($url));             $access_token = $res->access_token;             if ($access_token) {                 $redis->set('wechat:access_token', $access_token);                 $redis->expire('wechat:access_token', 7000);             }         }         return $access_token;     }     public static function curlGet($url = '', $options = array()){         $ch = curl_init($url);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($ch, CURLOPT_TIMEOUT, 30);         if (!empty($options)) {             curl_setopt_array($ch, $options);         }         //https请求 不验证证书和host         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);         $data = curl_exec($ch);         curl_close($ch);         return $data;     }     public static function curlPost($url = '', $postData = '', $options = array()){         if (is_array($postData)) {             $postData = http_build_query($postData);         }         $ch = curl_init();         curl_setopt($ch, CURLOPT_URL, $url);         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         curl_setopt($ch, CURLOPT_POST, 1);         curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);         curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数         if (!empty($options)) {             curl_setopt_array($ch, $options);         }         //https请求 不验证证书和host         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);         $data = curl_exec($ch);         curl_close($ch);         return $data;     }     public static function createNonceStr($length = 16){         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';         $str = '';         for ($i = 0; $i

    2.获取config参数接口public function actionConfig(){     if (isset($_REQUEST['url'])) {         $url = $_REQUEST['url'];         //微信支付参数         $appid = Yii::$app->params['wechat']['appid'];         $mchid = Yii::$app->params['wechat']['mchid'];         $key = Yii::$app->params['wechat']['key'];         $wx_pay = new WechatPay($mchid, $appid, $key);         $package = $wx_pay->getSignPackage($url);         $result['error'] = 0;         $result['msg'] = '获取成功';         $result['config'] = $package;     } else {         $result['error'] = 1;         $result['msg'] = '参数错误';     }     return $result; }

    作者:八宝粥BBZ

    链接:https://www.jianshu.com/p/8ebeb8ff6cee

    展开全文
  • 微信公众平台开发之自定义菜单管理是子恒老师《微信公众平台...详细讲解了用php开发微信,对微信公众平台中的自定义管理开发。内容包含微信添加菜单,获取自定义菜单配置,删除菜单等等。欢迎反馈,微信/QQ:68183131
  • 2、公众号配置和开发等,公众号菜单可以手动配置也可以代码设置, (1)、手动设置:公众号菜单自定义 (2)、代码设置:配置公众号服务器(服务器域名提供一个验证微信请求的接口CSDN)- &...
  • 本文实例为大家分享了php微信文本消息自动回复 别代码,供大家参考,具体内容如下1.PHP示例代码下载下载地址1:http://xiazai.ddpool.cn/201608/yuanma/phpwx(ddpool.cn).rar下载地址2:...》接入指南-》PHP示例代码...
  • 微信公众号开发php如何实现自定义关键字回复发布时间:2021-03-12 09:45:29来源:亿速云阅读:60作者:小新小编给大家分享一下之微信公众号开发php如何实现自定义关键字回复,相信大部分人都还不怎么了解,因此...
  • 1.微信支付也有很多种方式,今天我们所介绍的是公众号支付这种方式。这也是本人第一次进行微信开发,可能有一些地方介绍不到位,请见谅。Java版本【微信支付】API对应的SDK和调用示例的工具下载。3.生成超链接跳转到...
  • 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);i...
  • 摘要:模板消息仅用于公众号向用户发送重要的服务通知,只能用于符合其要求的服务场景中,如信用卡刷卡通知,商品购买成功通知等。不支持广告等营销类消息以及其它所有可能对用户造成骚扰的消息。 模板消息仅用于...
  • 话不多说,直接上代码:这个是ThinkPHP框架自动生成的目录,首先我们在Home/Common文件夹下创建一个文件Wechat.class.php,这个是微信公众号的基础框架,官网可以下载,直接导进来就可以了。该类是一个抽象类,主要...
  • 公众号支付、微信扫码支付、刷卡支付、微信买单此文来聊聊微信中的业务通知----微信模板消息如何查看是否有权限在交流群中,总是有人问个人订阅号、认证的订阅号、服务号 、认证的服务号 某个接口是否有权限使用。...
  • 微信公众号为服务号且开通微信认证(其他类型账号不能发送) 申请备案个线上域名 公众号设置->功能设置,配置网页授权域名 进入基础设置,开通开发者密码(AppSecret),并保存起来 ip白名单设置你的服务器...
  • 在前面的文章中已经分享过微信公众号API接口在应用中的接入验证,今天继续分享微信公众号的接收事件推送并回复的开发(关注微信号后自动回复消息,以及通过下面的消息发送向公众号发送消息时的回复)。虽然在微信公众...
  • 而对于某些具备开发能力的公众号运营者,可以通过高级群发接口,实现更灵活的群发能力。 在公众平台网站上,为订阅号提供了每天一条的群发权限,为服务号提供每月(自然月)4条的群发权限。而对于某些具备开发能力的...
  • 我们在微信公众号开发过程中经常会需要向用户推送消息,最常用到的就是微信公众号模板消息了,下面是代码工坊整理的php实现微信公众号模板消息的使用思路。1、开通模板消息功能。2、添加模板消息模板。3、代码中首先...
  • 推荐一个网站模拟登录微信公共平台,实现主动信息发送;突破订阅号一天只能发送一条信息的限制。使用编码UTF-8代码地址:https://github.com/itziy/wechat使用方法:$arr = array( 'account' => '公众平台帐号', ...
  • // gh_e79a177814ed //判断该数据包是否是订阅的事件推送 if( strtolower( $postObj->MsgType) == 'event'){ //如果是关注 subscribe 事件 if( strtolower($postObj->Event == 'subscribe') ){ //回复用户消息(纯...
  • 这两天自己想学习微信公众号开发,于是在网上搜索并上手练习,在这个过程中因为各种问题,(描述不完整,有的文章不知道怎么就蹦出个新的常量,也没说在哪定义的,还有jar包版本的问题坑了我一天的时间)所以特此在这...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,554
精华内容 8,621
关键字:

php微信公众号消息开发