侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

php微信公众账号开发之前五个坑(一)

微信(小程序)  /  管理员 发布于 7年前   189

直入主题:

微信公众账号开发文档,官方版(https://mp.weixin.qq.com/wiki),相信我,我已经无力吐槽写这个文档的人了,我真心想杂碎这个键盘,但是下手之后才发现,原来键盘是我自己花钱买的。。。。尴尬了。 

废话不说,直接说怎么部署,怎么开发。 

首先,你得有一个公众平台账号,好了,开始计坑。 

第一坑,不要以为不是企业号就不能开发了,可以申请测试号的,比所谓的订阅号接口多多了。

 

进入后台管理之后,点击开发者工具,可以看到公众平台测试账号,直接进入即可。开始填写自己的配置。 


注意涂鸦部分,这部分是程序中必须要配置的东东,如果没有配置的话,这是一定不成功的。 

第二坑,当然,你这么配置也一定是不成功的,不要问我为什么。没图说个几把。。。 


请不要认为企鹅帝闹着玩,这是真的,必须是80端口,其实也就发布一个域名的网站即可。因为域名的网站都是80端口出来的,继续说正题。 

企鹅帝告诉我们,要用微信账号,必须有一台服务器,然后配置我们发布的网站就行了,请注意,token是自己设定的,这个不是自动生成的,自己设定。。URL就是我们发布的网站名称 

第三坑,网站不发布,接口配置信息是永远配置不过去的,记住,是永远。 

JS接口安全域名,这个请直接参考文档(http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html)。 

JS接口安全域名的目的是为了下载图片,调用微信图片接口等等,比如当你需要调用摄像头的时候,或者说说需要上传照片的时候,这时候就需要JS安全接口了,关于具体的内容暂不做详细描述。 

在微信公众账号测试号的版本后台中,有一个体验接口权限表里面的这一项也是必须配置的。也不算是必须配置,而是这个接口可以获取到微信用户的部分信息。值得提醒的是每个公众账号对应的每个ID是唯一的,也就是说,即便网站内网不变,如果换了公众号,那么,这时候的微信公众号的数据是不能共通的,只是相对公共号唯一。 

第四坑,申请微信网页授权的时候,这里的网页授权用户基本信息,这个本身没问题,但是没有提示就有问题了。 

这里的网址,请注意,一定是不含www的,而且后面没有反斜杠,也就是说这里的网址的回调格式是  abc.com OK,请记住这个格式,必须这么干。好了,服务器暂且这样,暂开始用代码说话。 

首先从服务器验证说起。这个在官网是有例子的,不过是PHP的,其实说白了首先就是验证一个随机数,然后在POST的情况下,检测返回值即可。直接上代码 

 public ActionResult Index() { if (Request.HttpMethod.ToLower() == "post") { if (CheckSignature())//验证服务器是否通过 { GetMenuList();//加载菜单 } else { Response.Write("

Oh

我们相遇在火星吧!!!

"); Response.End(); } } else { CheckWechat(); } return View(); } /// /// 返回随机数表示验证成功 /// private void CheckWechat() { if (string.IsNullOrEmpty(Request.QueryString["echoStr"])) { Response.Write("消息并非来自微信"); Response.End(); } string echoStr = Request.QueryString["echoStr"]; if (CheckSignature()) { Response.Write(echoStr); Response.End(); } }/// /// 验证微信签名 /// /// /// 将token、timestamp、nonce三个参数进行字典序排序 /// 将三个参数字符串拼接成一个字符串进行sha1加密 /// 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信。 private bool CheckSignature() { string signature = Convert.ToString(Request["signature"]); string timestamp = Convert.ToString(Request["timestamp"]); string nonce = Convert.ToString(Request["nonce"]); string[] ArrTmp = { Token, timestamp, nonce }; Array.Sort(ArrTmp); //字典排序 string tmpStr = string.Join("", ArrTmp); tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1"); tmpStr = tmpStr.ToLower(); if (tmpStr == signature) { return true; } else { return false; } }

然后,公众平台在有权限的情况下是自定义菜单的,但是一旦开始自定义菜单,原来的手动编辑的菜单是不能用的,也就是说,如果服务器验证通过,那么必须用自己的代码控制。 

我们一起来看GetMenuList()这个方法,这个其实很简单的,就是随便凭借一个JSON格式字符串。然后调用微信的接口即可。  public void GetMenuList()   

 {  string weixin1 = "";  weixin1 = @" {  ""button"":[  {  ""type"":""click"",  ""name"":""你好!"",  ""key"":""hello""  },  {  ""type"":""view"",  ""name"":""公司简介"",  ""url"":""http://www.xnfhtech.com""  },  {  ""name"":""产品介绍"",  ""sub_button"":[  {  ""type"":""click"",  ""name"":""产品1"",  ""key"":""p1""  },  {  ""type"":""click"",  ""name"":""产品2"",  ""key"":""p2""  }]  }] }";   string access_token = Tools.WA_GetAccess_Token.IsExistAccess_Token();  string i = this.MenuCreate(menu, access_token);  Response.Write(i);  }

 public string MenuCreate(string MenuJson, string access_token) { JavaScriptSerializer Jss = new JavaScriptSerializer(); string setMenuUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}"; setMenuUrl = string.Format(setMenuUrl, access_token);//获取token、拼凑url string respText = WebRequestPostOrGet(setMenuUrl, MenuJson); Dictionary respDic = (Dictionary)Jss.DeserializeObject(respText); return respDic["errcode"].ToString();//返回0发布成功 } ///  /// Post/get 提交调用抓取 ///  /// 提交地址 /// 参数 /// string public string WebRequestPostOrGet(string sUrl, string sParam) { byte[] bt = System.Text.Encoding.UTF8.GetBytes(sParam); Uri uriurl = new Uri(sUrl); HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(uriurl);//HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url + (url.IndexOf("?") > -1 ? "" : "?") + param); req.Method = "Post"; req.Timeout = 120 * 1000; req.ContentType = "application/x-www-form-urlencoded;"; req.ContentLength = bt.Length; using (Stream reqStream = req.GetRequestStream())//using 使用可以释放using段内的内存 { reqStream.Write(bt, 0, bt.Length); reqStream.Flush(); } try { using (WebResponse res = req.GetResponse()) { //在这里对接收到的页面内容进行处理 Stream resStream = res.GetResponseStream(); StreamReader resStreamReader = new StreamReader(resStream, System.Text.Encoding.UTF8); string resLine; System.Text.StringBuilder resStringBuilder = new System.Text.StringBuilder(); while ((resLine = resStreamReader.ReadLine()) != null) {  resStringBuilder.Append(resLine + System.Environment.NewLine); } resStream.Close(); resStreamReader.Close(); return resStringBuilder.ToString(); } } catch (Exception ex) { return ex.Message;//url错误时候回报错 } }

好吧,我承认我是一个不明真相的吃货,怎么又多了一个access_token=IsExistAccess_Token();呢,莫着急,宝宝告诉你。

当我们阅读文档的时候,我们会发现,这里的Access_Token是每两个小时就过期的。这里的方法就是让他过期的时候自动获取。 

第五坑,这里的JSON字符串,也就是要展示的菜单,我希望大家都用小写,如果用了大写,那么,呵呵,哈哈了真心的,很操蛋的,他会告诉你没有用UTF8编码,但是你真心是编码过的,可惜还是出错,所以,还是小写吧,唉 

继续说两个小时自动获取之后,就是通过MenuCreate(调用微信菜单接口)输出即可。上代码。 

/// /// 防止每次请求的token两个小时的变化/// public class WA_GetAccess_Token{ public WA_GetAccess_Token() { } public static WAEntity.Access_token GetAccess_Token() { string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ ConfigurationManager.AppSettings["AppID"] + "&secret="+ ConfigurationManager.AppSettings["AppSecret"]; Access_token entity = new Access_token(); try { HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url); req.Method = "GET"; using (WebResponse wr = req.GetResponse()) { HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse(); StreamReader reader = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8); string content = reader.ReadToEnd(); Access_token token = new Access_token(); token = JsonHelper.ParseFromJson(content); entity.access_token = token.access_token; entity.expires_in = token.expires_in; } } catch{ //记录日志} return entity; } ///   /// 根据当前日期 判断Access_Token 是否超期 如果超期返回新的Access_Token 否则返回之前的Access_Token  ///   ///   ///   public static string IsExistAccess_Token() { try { string Token = string.Empty; DateTime YouXRQ; //读取XML文件中的数据,并显示出来 string filepath = HttpContext.Current.Request.MapPath("~/XMLFile.xml"); StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8); XmlDocument xml = new XmlDocument(); xml.Load(str); str.Close(); str.Dispose(); Token = xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText; YouXRQ = Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText); if (DateTime.Now > YouXRQ) { DateTime _youxrq = DateTime.Now; WAEntity.Access_token mode = GetAccess_Token(); xml.SelectSingleNode("xml").SelectSingleNode("Access_Token").InnerText = mode.access_token; _youxrq = _youxrq.AddSeconds(Convert.ToInt32(mode.expires_in)); xml.SelectSingleNode("xml").SelectSingleNode("Access_YouXRQ").InnerText = _youxrq.ToString(); xml.Save(filepath); Token = mode.access_token; } return Token; } catch (Exception ex) { return "";//记录日志 } }} public class Access_token{ public Access_token() { } public string access_token { get; set; } public string expires_in { get; set; }} public class JsonHelper{ ///   /// 生成Json格式  ///   ///   ///   ///   public static string GetJson(T obj) { DataContractJsonSerializer json = new DataContractJsonSerializer(obj.GetType()); using (MemoryStream stream = new MemoryStream()) { json.WriteObject(stream, obj); string szJson = Encoding.UTF8.GetString(stream.ToArray()); return szJson; } } ///   /// 获取Json的Model  ///   ///   ///   ///   public static T ParseFromJson(string szJson) { T obj = Activator.CreateInstance(); using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson))) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType()); return (T)serializer.ReadObject(ms); } }}

原谅我又不明真相了,所谓的XMLFile.xml这又是什么鬼,好吧,我其实不想说的这么直白的,还是代码直接上比较好。

 获取TOKEN 2015/9/12 17:56:31

我确定这个你真心不想说什么了 

好吧,默默的吃着瓜子,静静的看着你们继续,今天就先到这里,随后我们继续走起,已经五个坑了呀,宝宝心里苦呀。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

  • php微信公众账号开发之五个坑(二)
  • php版微信公众号自定义分享内容实现方法
  • 微信公众号开发之文本消息自动回复php代码
  • 微信公众号开发之语音消息识别php代码
  • Thinkphp微信公众号支付接口
  • php判断用户是否关注微信公众号
  • php实现微信公众号主动推送消息
  • 微信支付PHP SDK之微信公众号支付代码详解
  • php版微信公众平台接口参数调试实现判断用户行为的方法
  • php使用CURL模拟GET与POST向微信接口提交及获取数据的方法
  • php版微信公众账号第三方管理工具开发简明教程


  • 上一条:
    php微信公众账号开发之五个坑(二)
    下一条:
    微信支付的开发流程详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 微信模板消息改版后发送规则记录(微信订阅消息参数值内容限制说明)(1个评论)
    • 微信支付v3对接所需工具及命令(0个评论)
    • 2023年9月1日起:微信小程序必须备案才能上线运营(0个评论)
    • 腾讯官方客服回应了:微信好友上限约10000个!(1个评论)
    • 2023年做微信小程序的老铁注意:新增收费项、微信小程序获取手机号也收费了(2个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客