Home  >  Article  >  WeChat Applet  >  Problems before the development of php WeChat public account

Problems before the development of php WeChat public account

高洛峰
高洛峰Original
2017-03-21 16:08:021394browse

This article mainly introduces the five pitfalls before the development of PHP WeChat public accounts in detail. It has certain reference value. Interested friends can refer to the

WeChat public account development document, official Version (https://mp.weixin.qq.com/wiki)

First of all, you must have a public platform account. Okay, let’s start planning the trap.

The first pitfall, Don’t think that you can’t develop if you don’t have an enterprise account. There are many more interfaces that can apply for a test account than the so-called subscription account interface.

Problems before the development of php WeChat public account

After entering the background management, click on the developer tools, you can see the public platform test account, and enter directly. Start filling in your own configuration.

Problems before the development of php WeChat public account

Problems before the development of php WeChat public account

Pay attention to the graffiti part. This part is something that must be configured in the program. If it is not configured, this is It will definitely not be successful.

The second pit, of course, your configuration must be unsuccessful. Don’t ask me why. I don’t have a picture to say a few words. . .

Problems before the development of php WeChat public account

#Please don’t think that Emperor Penguin is joking. This is true. It must be port 80. In fact, it is just a website with a domain name. Because the domain name websites are all out of port 80, let’s continue with the topic.

Emperor Penguin told us that to use a WeChat account, we must have a server and then configure the website we publish. Please note that the token is set by yourself. This is not automatically generated. set up. . The URL is the name of the website we publish

The third pitfall is that if the website is not published, the interface configuration information will never be configured. Remember, it is forever.

The purpose of the JS interface secure domain name is to download pictures, call the WeChat picture interface, etc. For example, when you need to call the camera, or when you need to upload photos, you need a JS secure interface. , the specific content will not be described in detail for the time being.

In the version background of the WeChat public account test account, there is an experience interface permission table that must be configured. It is not necessary to configure, but this interface can obtain some information of WeChat users. It is worth reminding that each ID corresponding to each public account is unique. In other words, even if the intranet of the website remains unchanged, if the public account is changed, the data of the WeChat public account at this time cannot be shared. is only unique relative to the public number.

Problems before the development of php WeChat public account

The fourth pit, When applying for WeChat webpage authorization, here is the basic information of the webpage authorized user, this There is no problem in itself, but there is a problem if there is no prompt.

Problems before the development of php WeChat public account

The URL here, please note that must not contain www, and there is no backslash after it, that is It says that the callback format of the URL here is abc.com OK, please remember this format, you must do this. Okay, let’s leave the server like this for now and let’s start talking in code.

First let’s start with server verification. There is an example of this on the official website, but it is for PHP. In fact, to put it bluntly, the first step is to verify a random number, and then in the case of POST, detect the return value. Directly upload the code


 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;
 }
 }

Then, the public platform can customize the menu if it has permission, but once you start customizing the menu, the original manually edited menu cannot be In other words, if the server verification passes, you must use your own code to control it.

我们一起来看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>

The above is the detailed content of Problems before the development of php WeChat public account. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn