国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁(yè) 微信小程式 微信開(kāi)發(fā) php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

Mar 21, 2017 pm 04:08 PM
php微信開(kāi)發(fā)

這篇文章主要為大家詳細(xì)介紹了php微信公眾帳號(hào)開(kāi)發(fā)之前五個(gè)坑,具有一定的參考價(jià)值,有興趣的小伙伴們可以參考一下

微信公眾帳號(hào)開(kāi)發(fā)文檔,官方版(https://mp.weixin.qq.com/wiki)

首先,你得有個(gè)公眾平臺(tái)帳號(hào),好了,開(kāi)始計(jì)坑。?

第一坑,不要以為不是企業(yè)號(hào)就不能開(kāi)發(fā)了,可以申請(qǐng)測(cè)試號(hào)碼的,比所謂的訂閱號(hào)碼介面多多了。

?

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

進(jìn)入背景管理之後,點(diǎn)選開(kāi)發(fā)者工具,可以看到公眾平臺(tái)測(cè)試帳號(hào),直接進(jìn)入即可。開(kāi)始填寫(xiě)自己的配置。

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

注意塗鴉部分,這部分是程式中必須要設(shè)定的東東,如果沒(méi)有設(shè)定的話,這是一定不成功的。?

第二個(gè)坑,當(dāng)然,你這麼配置也一定是不成功的,不要問(wèn)我為什麼。沒(méi)圖說(shuō)個(gè)幾把。 。 。?

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

請(qǐng)不要認(rèn)為企鵝帝鬧著玩,這是真的,必須是80端口,其實(shí)也就發(fā)布一個(gè)域名的網(wǎng)站即可。因?yàn)榫W(wǎng)域的網(wǎng)站都是80埠出來(lái)的,繼續(xù)說(shuō)正題。

企鵝帝告訴我們,要用微信帳號(hào),必須有一臺(tái)伺服器,然後配置我們發(fā)布的網(wǎng)站就行了,請(qǐng)注意,token是自己設(shè)定的,這個(gè)不是自動(dòng)生成的,自己設(shè)定。 。 URL就是我們發(fā)布的網(wǎng)站名稱(chēng)?

第三坑,網(wǎng)站不發(fā)布,介面設(shè)定資訊是永遠(yuǎn)配置不過(guò)去的,記住,是永遠(yuǎn)。

JS介面安全網(wǎng)域的目的是為了下載圖片,呼叫微信圖片介面等等,例如當(dāng)你需要呼叫相機(jī)的時(shí)候,或是說(shuō)說(shuō)需要上傳照片的時(shí)候,這時(shí)候就需要JS安全介面了,關(guān)於具體的內(nèi)容暫不做詳細(xì)描述。?

在微信公用帳號(hào)測(cè)試號(hào)碼的版本後臺(tái)中,有一個(gè)體驗(yàn)介面權(quán)限表裡面的這項(xiàng)也是必須設(shè)定的。也不算是必須配置,而是這個(gè)介面可以取得到微信用戶(hù)的部分資訊。值得提醒的是每個(gè)公眾帳號(hào)對(duì)應(yīng)的每個(gè)ID是唯一的,也就是說(shuō),即便網(wǎng)站內(nèi)網(wǎng)不變,如果換了公眾號(hào),那麼,這時(shí)候的微信公眾號(hào)的數(shù)據(jù)是不能共通的,只是相對(duì)公共號(hào)唯一。 ?

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

第四坑,申請(qǐng)微信網(wǎng)頁(yè)授權(quán)的時(shí)候,這裡的網(wǎng)頁(yè)授權(quán)使用者基本信息,這個(gè)本身沒(méi)問(wèn)題,但是沒(méi)有提示就有問(wèn)題了。

php微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題

這裡的網(wǎng)址,請(qǐng)注意,一定是不含www的,而且後面沒(méi)有反斜線,也就是說(shuō)這裡的網(wǎng)址的回呼格式是? abc.com OK,請(qǐng)記住這個(gè)格式,必須這麼做。好了,伺服器暫且這樣,暫開(kāi)始用程式碼說(shuō)話。?

先從伺服器驗(yàn)證開(kāi)始。這個(gè)在官網(wǎng)是有例子的,不過(guò)是PHP的,其實(shí)說(shuō)白了首先就是驗(yàn)證一個(gè)隨機(jī)數(shù),然後在POST的情況下,檢測(cè)回傳值即可。直接上程式碼?


 public ActionResult Index()
 {
 if (Request.HttpMethod.ToLower() == "post")
 {
 if (CheckSignature())//驗(yàn)證服務(wù)器是否通過(guò)
 {
 GetMenuList();//加載菜單
 }
 else
 {
 Response.Write("<h1>Oh</h1><h2>我們相遇在火星吧?。?!</h2>");
 Response.End();
 }
 }
 else
 {
 CheckWechat();
 }
 return View();
 }

 

 /// <summary>
 /// 返回隨機(jī)數(shù)表示驗(yàn)證成功
 /// </summary>
 private void CheckWechat()
 {
 if (string.IsNullOrEmpty(Request.QueryString["echoStr"]))
 {
 Response.Write("消息并非來(lái)自微信");
 Response.End();
 }
 string echoStr = Request.QueryString["echoStr"];
 if (CheckSignature())
 {
 Response.Write(echoStr);
 Response.End();
 }
 }

/// <summary>
 /// 驗(yàn)證微信簽名
 /// </summary>
 /// <returns></returns>
 /// 將token、timestamp、nonce三個(gè)參數(shù)進(jìn)行字典序排序
 /// 將三個(gè)參數(shù)字符串拼接成一個(gè)字符串進(jìn)行sha1加密
 /// 開(kāi)發(fā)者獲得加密后的字符串可與signature對(duì)比,標(biāo)識(shí)該請(qǐng)求來(lái)源于微信。
 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;
 }
 }

然後,公眾平臺(tái)在有權(quán)限的情況下是自訂選單的,但是一旦開(kāi)始自訂選單,原來(lái)的手動(dòng)編輯的選單是不能用的,也就是說(shuō),如果伺服器驗(yàn)證通過(guò),那麼就必須用自己的程式碼控制。?

#

我們一起來(lái)看GetMenuList()這個(gè)方法,這個(gè)其實(shí)很簡(jiǎn)單的,就是隨便憑借一個(gè)JSON格式字符串。然后調(diào)用微信的接口即可。 public void GetMenuList()


<em id="__mceDel"> { 
 string weixin1 = ""; 
 weixin1 = @" { 
 ""button"":[ 
 { 
 ""type"":""click"", 
 ""name"":""你好!"", 
 ""key"":""hello"" 
 }, 
 { 
 ""type"":""view"", 
 ""name"":""公司簡(jiǎn)介"", 
 ""url"":""http://www.xnfhtech.com"" 
 }, 
 { 
 ""name"":""產(chǎn)品介紹"", 
 ""sub_button"":[ 
 { 
 ""type"":""click"", 
 ""name"":""產(chǎn)品1"", 
 ""key"":""p1"" 
 }, 
 { 
 ""type"":""click"", 
 ""name"":""產(chǎn)品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發(fā)布成功
 }

 

/// <summary>
 /// Post/get 提交調(diào)用抓取
 /// </summary>
 /// <param name="url">提交地址</param>
 /// <param name="param">參數(shù)</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段內(nèi)的內(nèi)存
 {
 reqStream.Write(bt, 0, bt.Length);
 reqStream.Flush();
 }
 try
 {
 using (WebResponse res = req.GetResponse())
 {
 //在這里對(duì)接收到的頁(yè)面內(nèi)容進(jìn)行處理
 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錯(cuò)誤時(shí)候回報(bào)錯(cuò)
 }

 }

好吧,我承認(rèn)我是一個(gè)不明真相的吃貨,怎么又多了一個(gè)access_token=IsExistAccess_Token();呢,莫著急,寶寶告訴你。

當(dāng)我們閱讀文檔的時(shí)候,我們會(huì)發(fā)現(xiàn),這里的Access_Token是每?jī)蓚€(gè)小時(shí)就過(guò)期的。這里的方法就是讓他過(guò)期的時(shí)候自動(dòng)獲取。

第五坑,這里的JSON字符串,也就是要展示的菜單,我希望大家都用小寫(xiě),如果用了大寫(xiě),那么,呵呵,哈哈了真心的,很操蛋的,他會(huì)告訴你沒(méi)有用UTF8編碼,但是你真心是編碼過(guò)的,可惜還是出錯(cuò),所以,還是小寫(xiě)吧,唉

繼續(xù)說(shuō)兩個(gè)小時(shí)自動(dòng)獲取之后,就是通過(guò)MenuCreate(調(diào)用微信菜單接口)輸出即可。上代碼。


/// <summary>
/// 防止每次請(qǐng)求的token兩個(gè)小時(shí)的變化
/// </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> 
 /// 根據(jù)當(dāng)前日期 判斷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文件中的數(shù)據(jù),并顯示出來(lái)
 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這又是什么鬼,好吧,我其實(shí)不想說(shuō)的這么直白的,還是代碼直接上比較好。


<?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微信公眾號(hào)開(kāi)發(fā)前的問(wèn)題的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門(mén)話題

Laravel 教程
1600
29
PHP教程
1502
276