• 技术文章 >微信小程序 >微信开发

    php微信公众号开发前的问题

    高洛峰高洛峰2017-03-21 16:08:02原创730
    这篇文章主要为大家详细介绍了php微信公众账号开发之前五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    微信公众账号开发文档,官方版(https://mp.weixin.qq.com/wiki)

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

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

    php微信公众号开发前的问题

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

    php微信公众号开发前的问题

    php微信公众号开发前的问题

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

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

    php微信公众号开发前的问题

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

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

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

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

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

    php微信公众号开发前的问题

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

    php微信公众号开发前的问题

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

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


     public ActionResult Index()
     {
     if (Request.HttpMethod.ToLower() == "post")
     {
     if (CheckSignature())//验证服务器是否通过
     {
     GetMenuList();//加载菜单
     }
     else
     {
     Response.Write("<h1>Oh</h1><h2>我们相遇在火星吧!!!</h2>");
     Response.End();
     }
     }
     else
     {
     CheckWechat();
     }
     return View();
     }
    
     
    
     /// <summary>
     /// 返回随机数表示验证成功
     /// </summary>
     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();
     }
     }
    
    /// <summary>
     /// 验证微信签名
     /// </summary>
     /// <returns></returns>
     /// 将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()


    <em id="__mceDel"> { 
     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); 
     }<br><br>
    </em>


     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<string, object> respDic = (Dictionary<string, object>)Jss.DeserializeObject(respText);
     return respDic["errcode"].ToString();//返回0发布成功
     }
    
     
    
    /// <summary>
     /// Post/get 提交调用抓取
     /// </summary>
     /// <param name="url">提交地址</param>
     /// <param name="param">参数</param>
     /// <returns>string</returns>
     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(调用微信菜单接口)输出即可。上代码。


    /// <summary>
    /// 防止每次请求的token两个小时的变化
    /// </summary>
    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<Access_token>(content);
     entity.access_token = token.access_token;
     entity.expires_in = token.expires_in;
     }
    
     }
    
     catch{ //记录日志}
     return entity;
    
     }
    
     /// <summary> 
     /// 根据当前日期 判断Access_Token 是否超期 如果超期返回新的Access_Token 否则返回之前的Access_Token 
     /// </summary> 
     /// <param name="datetime"></param> 
     /// <returns></returns> 
     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
    {
     /// <summary> 
     /// 生成Json格式 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="obj"></param> 
     /// <returns></returns> 
     public static string GetJson<T>(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;
     }
     }
     /// <summary> 
     /// 获取Json的Model 
     /// </summary> 
     /// <typeparam name="T"></typeparam> 
     /// <param name="szJson"></param> 
     /// <returns></returns> 
     public static T ParseFromJson<T>(string szJson)
     {
     T obj = Activator.CreateInstance<T>();
     using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(szJson)))
     {
     DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
     return (T)serializer.ReadObject(ms);
     }
     }
    
    }

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


    <?xml version="1.0" encoding="utf-8"?>
    <xml>
     <Access_Token>获取TOKEN</Access_Token>
     <Access_YouXRQ>2015/9/12 17:56:31</Access_YouXRQ>
    </xml>

    以上就是php微信公众号开发前的问题的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:php微信开发
    上一篇:NodeJs开发微信公众号微信事件交互实例代码 下一篇:PHP微信开发之微信消息自动回复遇到的问题
    PHP编程就业班

    相关文章推荐

    • 微信支付开发全网发布• 微信聊天记录被删除了怎么恢复• 微信公众开发使用消息接的方法• NodeJs开发微信公众号微信事件交互实例代码• C#开发微信门户及应用(1)--开始使用微信接口

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网