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

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

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

上篇说到微信公众账号的几个坑,前面五个,已经说到菜单,宝宝继续往下赘述了。可惜,还不知道宝宝的宝宝到底是不是心疼宝宝呢,完了,我凌乱了。。。 

回到正题,我们就不吐槽其他的了,上一篇说到微信的菜单了,那么,我们现在说说菜单回复等等的吧。 

菜单回复是需要处理XML文件的,我们根据微信返回的XML文件,可以得到每个微信用户相对于微信公众号的唯一标识。微信公众平台的机制简单的将就是我们自己输出固定格式的xml文件,然后微信APP负责解析,得到我们想要的信息,然后对信息统一处理。 

第六坑,如果你看微信文档,那么,绝对坑死你,上图。这里的ToUserName和FromUserName一定特么的要分清楚了,记住,千万不要写反了,用户对于微信而言是A→B,那么微信对于用户就是反着来的,貌似现在应该说清楚了。

///  /// 接收微信发送的XML消息并且解析 ///  private void ReceiveXml() { try {  Stream requestStream = System.Web.HttpContext.Current.Request.InputStream;  byte[] requestByte = new byte[requestStream.Length];  requestStream.Read(requestByte, 0, (int)requestStream.Length);  string requestStr = Encoding.UTF8.GetString(requestByte);  if (!string.IsNullOrEmpty(requestStr))  {   //封装请求类  XmlDocument requestDocXml = new XmlDocument();  requestDocXml.LoadXml(requestStr);  XmlElement rootElement = requestDocXml.DocumentElement;  WxXmlModel WxXmlModel = new WxXmlModel();  if (rootElement != null)  {   WxXmlModel.ToUserName = rootElement.SelectSingleNode("ToUserName") == null ? "" : rootElement.SelectSingleNode("ToUserName").InnerText;   WxXmlModel.FromUserName = rootElement.SelectSingleNode("FromUserName") == null ? "" : rootElement.SelectSingleNode("FromUserName").InnerText;   WxXmlModel.CreateTime = rootElement.SelectSingleNode("CreateTime") == null ? "" : rootElement.SelectSingleNode("CreateTime").InnerText;   WxXmlModel.MsgType = rootElement.SelectSingleNode("MsgType") == null ? "" : rootElement.SelectSingleNode("MsgType").InnerText;   switch (WxXmlModel.MsgType)   {   case "text"://文本    WxXmlModel.Content = rootElement.SelectSingleNode("Content") == null ? "" : rootElement.SelectSingleNode("Content").InnerText;    break;   case "image"://图片    WxXmlModel.PicUrl = rootElement.SelectSingleNode("PicUrl") == null ? "" : rootElement.SelectSingleNode("PicUrl").InnerText;    break;   case "event"://事件    WxXmlModel.Event = rootElement.SelectSingleNode("Event") == null ? "" : rootElement.SelectSingleNode("Event").InnerText;    if (WxXmlModel.Event != "TEMPLATESENDJOBFINISH")//关注类型    {    WxXmlModel.EventKey = rootElement.SelectSingleNode("EventKey") == null ? "" : rootElement.SelectSingleNode("EventKey").InnerText;    }    break;   default:    break;   }  }  ResponseXML(WxXmlModel);//回复消息  }  } catch (Exception ee) {  //记录错误日志 } } ///  /// 回复消息 ///  ///  private void ResponseXML(WxXmlModel WxXmlModel) { string XML = ""; switch (WxXmlModel.MsgType) {  case "text"://文本回复  var info = oauth.GetUserInfo(Tools.WA_GetAccess_Token.IsExistAccess_Token(), WxXmlModel.FromUserName);  Tools.WAEntity.OAuthUser user = Tools.JsonHelper.ParseFromJson(info);  var content = WxXmlModel.Content.ToUpper();  string NcbActUrl = ConfigurationManager.AppSettings["NcbActUrl"];  string appid = ConfigurationManager.AppSettings["AppID"];  if (content.Contains("T"))//接受的文字如果包含T  {   //业务处理  }  else  {   XML = ResponseMessage.ReText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, "/:rose农场大数据欢迎你!/:rose");  }  break;  case "event":  switch (WxXmlModel.Event.ToLower())  {   case "subscribe":   if (string.IsNullOrEmpty(WxXmlModel.EventKey))   {    XML = ResponseMessage.ReText(WxXmlModel.FromUserName, WxXmlModel.ToUserName, "关注成功!/:rose");   }   else   {    XML = ResponseMessage.SubScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码先关注后推送事件   }   break;   case "scan":   XML = ResponseMessage.ScanQrcode(WxXmlModel.FromUserName, WxXmlModel.ToUserName, WxXmlModel.EventKey);//扫描带参数二维码已关注 直接推送事件   break;   case "click"://处理单击事件   if (WxXmlModel.EventKey == "p1")   {    //自己的业务逻辑   }   else   {    //自己的业务逻辑   }   break;   case "unsubscribe"://取消关注   break;  }  break;  default://默认回复  break; } Response.Write(XML);//输出组织的XML信息 }

这就是菜单的信息处理,不明真相的群众貌似会问那个所谓的ResponseMessage到底有几个意思呢,OK,我已经无力吐槽我这三天研究出来的微信公共平台的东西了。 

public class ResponseMessage{ #region 接收的类型 ///  /// 接收文本 ///  ///  ///  ///  ///  public static string GetTextTest(string FromUserName, string ToUserName, string Content, string key) { CommonMethod.WriteTxt(Content);//接收的文本消息 string XML = ""; switch (Content) {  case "关键字":  XML = ReText(FromUserName, ToUserName, "关键词回复测试――兴农丰华:" + key);  break;  case "单图文":  XML = ReArticle(FromUserName, ToUserName, "测试标题", "测试详情――兴农丰华:" + key, "http://www.xnfhtech.com/templets/boze/images/20120130083143544.gif", "http://www.xnfhtech.com/");  break;  default:  XML = ReText(FromUserName, ToUserName, "无对应关键字――兴农丰华:" + key);  break; } return XML; } ///  /// 未关注扫描带参数二维码 ///  ///  ///  ///  ///  public static string SubScanQrcode(string FromUserName, string ToUserName, string EventKey) { return ""; }  ///  /// 已关注扫描带参数二维码 ///  ///  ///  ///  ///  public static string ScanQrcode(string FromUserName, string ToUserName, string EventKey) { return ""; } #endregion  #region 回复方式 ///  /// 回复文本 ///  /// 发送给谁(openid) /// 来自谁(公众账号ID) /// 回复类型文本 /// 拼凑的XML public static string ReText(string FromUserName, string ToUserName, string Content) { string XML = "";//发送给谁(openid),来自谁(公众账号ID) XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳 XML += "";//回复类型文本 XML += "0";//回复内容 FuncFlag设置为1的时候,自动星标刚才接收到的消息,适合活动统计使用 return XML; }  ///  /// 回复单图文 ///  /// 发送给谁(openid) /// 来自谁(公众账号ID) /// 标题 /// 详情 /// 图片地址 /// 地址 /// 拼凑的XML public static string ReArticle(string FromUserName, string ToUserName, string Title, string Description, string PicUrl, string Url) { string XML = "";//发送给谁(openid),来自谁(公众账号ID) XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳 XML += "1"; XML += "<![CDATA[" + Title + "]]>"; XML += "0"; return XML; } ///  /// 多图文回复 ///  /// 发送给谁(openid) /// 来自谁(公众账号ID) /// 图文数量 ///  ///  public static string ReArticle(string FromUserName, string ToUserName, int ArticleCount, System.Data.DataTable dtArticle) { string XML = "";//发送给谁(openid),来自谁(公众账号ID) XML += "" + CommonMethod.ConvertDateTimeInt(DateTime.Now) + "";//回复时间戳 XML += "" + ArticleCount + ""; foreach (System.Data.DataRow Item in dtArticle.Rows) {  XML += "<![CDATA[" + Item["Title"] + "]]>"; } XML += "0"; return XML; } #endregion }

OK,加上自己的逻辑代码,是不是完美的实现了回复? 

第七坑,我真心不想计数了,你确定这个回复可以么?说真的,宝宝不确定,因为你写了之后知道在哪里调用么,我的乖乖,尼玛,服务器验证通过就把回复加上去是最保险的。我已经没有节操了。

接下来我们说什么呢,我们就说说获取用户信息这个东西吧,因为我们这些东西一般都是基于H5页面的。所以,就要用到之前我们配置的

这个东东,其实这个相对于前面的至少坑少了很多,真心的,宝宝就暂时不说他坑了。上个代码吧。 

//微信网页授权2.0public class Oauth2{ JavaScriptSerializer Jss = new JavaScriptSerializer(); public Oauth2() { }  ///  /// 对页面是否要用授权 ///  /// 微信应用id /// 回调页面 /// 应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) /// 授权地址 public string GetCodeUrl(string Appid, string redirect_uri, string scope) { return string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state=STATE#wechat_redirect", Appid, redirect_uri, scope); }  ///  /// 对页面是否要用授权 ///  /// 微信应用id /// 回调页面 /// 应用授权作用域snsapi_userinfo(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) /// 授权地址 public string GetCodeUrl(string Appid, string redirect_uri, string scope,string state) { return string.Format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&redirect_uri={1}&response_type=code&scope={2}&state={3}#wechat_redirect", Appid, redirect_uri, scope, state); }  ///  /// 用code换取openid 此方法一般是不获取用户昵称时候使用 ///  ///  ///  /// 回调页面带的code参数 /// 微信用户唯一标识openid public string CodeGetOpenid(string Appid, string Appsecret, string Code) { string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", Appid, Appsecret, Code); string ReText = CommonMethod.WebRequestPostOrGet(url, "");//post/get方法获取信息 Dictionary DicText = (Dictionary)Jss.DeserializeObject(ReText); if (!DicText.ContainsKey("openid"))  return ""; return DicText["openid"].ToString(); }  ///  ///用code换取获取用户信息(包括非关注用户的) ///  ///  ///  /// 回调页面带的code参数 /// 获取用户信息(json格式) public string GetUserInfo(string Appid, string Appsecret, string Code) { string url = string.Format("https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&secret={1}&code={2}&grant_type=authorization_code", Appid, Appsecret, Code); string ReText = CommonMethod.WebRequestPostOrGet(url, "");//post/get方法获取信息 Dictionary DicText = (Dictionary)Jss.DeserializeObject(ReText); if (!DicText.ContainsKey("openid")) {  log.Error("获取openid失败,错误码:" + DicText["errcode"].ToString()); return ""; } else {  return CommonMethod.WebRequestPostOrGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + DicText["access_token"] + "&openid=" + DicText["openid"] + "&lang=zh_CN", ""); } }   ///  /// 通过openId获取用户信息 ///  ///  ///  ///  public string GetUserInfo(string accesstoken, string openid) { string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN", accesstoken, openid); return CommonMethod.WebRequestPostOrGet(url, "");//post/get方法获取信息 }}

我们需要调用的时候直接用里面的方法,获取微信网页授权即可,比如对于A控制器下面的B视图要获取授权,并且要获取用户的相关信息,那么我们直接调用即可,如 GetCodeUrl(appid, "http://" + Url + "/A/B", "snsapi_userinfo")

在这里我还是吐槽一下吧。 

第八坑,微信菜单JSON的url拼接,里面的前面不是加了js验证么,so,特么的,还是乖乖的加上http://。 

不过这里授权之后,因为用户的很多信息我们都要用到,这就是H5页面传值的问题,我在项目里面用的是Session,直接写一个公用方法,如果Session有值,则直接取值的。对于里面的一些东东,我想说明一下,并不是所有的代码都要贴出来,我这边的代码只是我个人认为需要贴出来的。所以里面的方法可能有大家看不到的,如果需要,可以留言本宝宝,谢谢。 

public string getSession(){ log.Error("GetSession"); string oauthStr = ""; try { if (Session != null && (Session["oauthStr"] == null || string.IsNullOrEmpty(Session["oauthStr"].ToString()))) {  if (!string.IsNullOrEmpty(Request.QueryString["code"]))  {  Oauth2 oauth = new Oauth2();  string code = Convert.ToString(Request["code"]);  oauthStr = oauth.GetUserInfo(ConfigurationManager.AppSettings["AppID"],   ConfigurationManager.AppSettings["AppSecret"], code);   Session["oauthStr"] = oauthStr;  Tools.WAEntity.OAuthUser oAuthUser = new Tools.WAEntity.OAuthUser();  oAuthUser = Tools.JsonHelper.ParseFromJson(oauthStr);  }  return oauthStr; } else {  Tools.WAEntity.OAuthUser oAuthUser = new Tools.WAEntity.OAuthUser();  oAuthUser = Tools.JsonHelper.ParseFromJson(Session["oauthStr"].ToString());  return Session["oauthStr"].ToString(); } } catch (Exception e) { log.Error(e.ToString()); return oauthStr; };}

然后每次遇到需要获取信息的页面,我一般都是调用这个就可以了。 

基本上剩下的都是我们自己要处理的业务逻辑了,继续说坑吧。 

第九坑,微信上传图片,坑的绝对不只是自己。对于这个宝宝真的信了,不管你信不信。特么的图片不能for循环上传。当然,这个只限苹果机型,大Android还是没有问题的。
前面说到了JS安全验证的问题,这里就是调用这些个验证,请求一些应该的权限,然后获取图片信息等等。 

放心好了,宝宝现在都是上图说话,没图说个小弟弟呀。。。。。 

我们继续回来看代码。 

先来个处理Json的

public class JsApi{ JavaScriptSerializer Jss = new JavaScriptSerializer();  public JsApi() { }  const string URL_FORMAT_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi"; #region 验证JsApi权限配置 ///  /// 获取JsApi权限配置的数组/四个参数 ///  /// 应用id /// 密钥 /// json格式的四个参数 public string GetJsApiInfo(string Appid, string Appsecret) { string jsapi_ticket = ""; //ticket 缓存7200秒 if (System.Web.HttpContext.Current.Session["jsapi_ticket"] == null) {  string ticketurl = string.Format(URL_FORMAT_TICKET, BasicApi.GetAccessToken(Appid, Appsecret));//"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + GetAccessToken(Appid, Appsecret) + "&type=jsapi"  jsapi_ticket = CommonMethod.WebRequestPostOrGet(ticketurl, "");//BasicApi.GetTokenSession  System.Web.HttpContext.Current.Session["jsapi_ticket"] = jsapi_ticket;  System.Web.HttpContext.Current.Session.Timeout = 7200;  BasicApi.WriteTxt("jsapi_ticket1:" + jsapi_ticket); } else {  jsapi_ticket = System.Web.HttpContext.Current.Session["jsapi_ticket"].ToString();  BasicApi.WriteTxt("jsapi_ticket2:" + jsapi_ticket); }  Dictionary respDic = (Dictionary)Jss.DeserializeObject(jsapi_ticket); jsapi_ticket = respDic["ticket"].ToString();//获取ticket string timestamp = CommonMethod.ConvertDateTimeInt(DateTime.Now).ToString();//生成签名的时间戳 string nonceStr = CommonMethod.GetRandCode(16);//生成签名的随机串 string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri.ToString();//当前的地址 BasicApi.WriteTxt("url:" + url); string[] ArrayList = { "jsapi_ticket=" + jsapi_ticket, "timestamp=" + timestamp, "noncestr=" + nonceStr, "url=" + url }; Array.Sort(ArrayList); string signature = string.Join("&", ArrayList); signature = FormsAuthentication.HashPasswordForStoringInConfigFile(signature, "SHA1").ToLower(); string r = "{\"appId\":\"" + Appid + "\",\"timestamp\":" + timestamp + ",\"nonceStr\":\"" + nonceStr +   "\",\"signature\":\"" + signature +   "\",\"jsApiList\":[\"chooseImage\",\"previewImage\",\"uploadImage\",\"downloadImage\",\"scanQRCode\",\"onMenuShareQQ\"]}"; BasicApi.WriteTxt("r:" + r.Replace(" ", "")); return r.Replace(" ", ""); }}

然后看具体调用。

后台代码其实很简单的,直接输出配置文件,然后前台js直接调用即可。 

JsApi jsApi = new JsApi();string config = jsApi.GetJsApiInfo(appId, appSecret);ViewBag.config = config;

前台代码,其实也不难,这个有官方的例子的。 

OK,后台方法其实也很简单,就是一个二进制文件处理,不对,简单个蛋蛋,特么的,因为路径的问题,坑了宝宝一个小时,特么的。还有这里建议,等微信图片下载完成之后再给前台加载图片,保证每一个图片都加载完成,保证后台的图片的上传完成。 

/// /// 下载多媒体文件/// /// 公众号/// 媒体ID/// 返回下载是否成功/// 添加的图片类型/// 返回多媒体文件数据;如果下载失败,返回null。public JsonResult DownloadWxPhoto(string mediaId, int types){ ErrorMessage errorMessage; string access_token = BasicApi.GetAccessToken(ConfigurationManager.AppSettings["AppID"], ConfigurationManager.AppSettings["AppSecret"]); byte[] data = MediaHelper.Download(access_token, mediaId, out errorMessage); string files = String.Empty, fileName = String.Empty; files = Server.MapPath("~/Wxinphoto/"); if (!Directory.Exists(files)) { Directory.CreateDirectory(files); } fileName = files + DateTime.Now.Ticks + ".jpg"; if (data != null) { bool flag = writeFile(data, fileName); if (flag) {  errorMessage = new ErrorMessage(ErrorMessage.SuccessCode, "下载多媒体文件成功。"); } else {  errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "从微信服务器下载多媒体文件失败。"); } } else errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "从微信服务器下载多媒体文件失败。"); return Json(new { result = "/" + urlconvertor(fileName), errorMessage = errorMessage });}//读filename到byte[] private byte[] ReadFile(string fileName){ FileStream pFileStream = null; byte[] pReadByte = new byte[0]; try { pFileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read); BinaryReader r = new BinaryReader(pFileStream); r.BaseStream.Seek(0, SeekOrigin.Begin); //将文件指针设置到文件开 pReadByte = r.ReadBytes((int)r.BaseStream.Length); return pReadByte; } catch { return pReadByte; } finally { if (pFileStream != null)  pFileStream.Close(); }} //写byte[]到fileNameprivate bool writeFile(byte[] pReadByte, string fileName){ FileStream pFileStream = null; try { pFileStream = new FileStream(fileName, FileMode.OpenOrCreate); pFileStream.Write(pReadByte, 0, pReadByte.Length); } catch { return false; } finally { if (pFileStream != null)  pFileStream.Close(); } return true;}/// /// 判断目标字节数组是否位于源字节数组的开始/// /// 源字节数组/// 目标字节数组/// 返回目标字节数组是否位于源字节数组的开始private bool StartsWithBytes(byte[] source, byte[] target){ if (source == null && target == null) return true; if (source == null && target != null || source != null && target == null) return false; if (source.Length < target.Length) return false; bool startsWith = true; for (int i = 0; i < target.Length; i++) { if (source[i] != target[i]) {  startsWith = false;  break; } } return startsWith;}

 是不是以为这就算完事了,我的乖乖,头像上传了,微信摄像头也特么该调用的调用了,宝宝好幸福,宝宝也是牛人一个了,记住前面的东东,宝宝还没有说坑呢。
来重复我们的第九个坑,特么的,你JS写个for循环要是能循环把图片上传到后台,宝宝也服气,真的,宝宝服气。 

直接说吧,最后我自己想了下,也和队友讨论了下,可能是因为微信有什么验证,导致之后一张图片上传成功之后,才能进行一张,但是我们Iphone就是特么的特例,大Android没用问题的,就是Iphone有了问题,而且问题不小,上传四张图片吧,老特么是最后一张,最后,找到了万能的网友,感谢你,不过宝宝已经忘记了在哪里找到的了,尴尬了。。。。。。。。。。。 

请记住,递归就特么可以了。

说到这里,宝宝已经不想多说什么了,特么的产品你能不能不装逼,你特么见过那个微信能回复一个信息直接跳转网页的,你咋不去屎呢,联想到前几天大阿里的月饼时间,突然感觉我们程序员挺悲剧的,成功的都是特么的产品,然后出问题的都是我们程序员的锅?试问一下,这个锅真心我们程序员该背么。 

算了,还是不吐槽了,已经无力了。。。。宝宝92年降临,现在确实82年的皮肤呀,唉,宝宝累了,真的。 

顺便给点H5页面的建议吧。比如当点击返回键的时候,我们需要刷新页面的时候,就是所谓的判断页面要不要刷新,这里有很多种方法,但是微信里面宝宝还是觉得这么干靠谱。 

还有,那个微信执行完成之后想直接退出当前界面进入微信公众号界面的,直接调用微信的一个内置的方法即可。记得写到里面。 

WeixinJSBridge.call('closeWindow'); //这是微信关闭当前网页

这么自信的以为自己搞定了所有,你跑呀,你要跑起来,嗯哼,别不服气。 

微信公众账号指第十坑,我自己加的,哈哈,就是前面的JS验证的时候,你不要头文件,怎么搞定这些事情,哈哈。是不是宝宝赢了。Oh  perfect,I like it。

 这个东西一定不能忘记哈。

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

您可能感兴趣的文章:

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


  • 上一条:
    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交流群

    侯体宗的博客