热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

php微信公众账号开发遇到的五个坑总结

这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要为大家详细介绍了php微信公众账号开发之五个坑,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

菜单回复是需要处理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 += "";
 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 += "";
 }
 XML += "0";
 return XML;

 }

 #endregion

 }

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

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

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

//微信网页授权2.0
public 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安全验证的问题,这里就是调用这些个验证,请求一些应该的权限,然后获取图片信息等等。

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[]到fileName

private 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 

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

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


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

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

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

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


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

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

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

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

以上就是php微信公众账号开发遇到的五个坑总结的详细内容,更多请关注php中文网其它相关文章!


推荐阅读
  • 我一直都有记录信息的习惯,不知是从什么时候开始,大约是在工作后不久。如今还真有点庆幸从那时开始记了点东西,当然是电子版的,写 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • Unity3D引擎的体系结构和功能详解
    本文详细介绍了Unity3D引擎的体系结构和功能。Unity3D是一个屡获殊荣的工具,用于创建交互式3D应用程序。它由游戏引擎和编辑器组成,支持C#、Boo和JavaScript脚本编程。该引擎涵盖了声音、图形、物理和网络功能等主题。Unity编辑器具有多语言脚本编辑器和预制装配系统等特点。本文还介绍了Unity的许可证情况。Unity基本功能有限的免费,适用于PC、MAC和Web开发。其他平台或完整的功能集需要购买许可证。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
author-avatar
mobiledu2502915773
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有