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

java微信开发API第二步获取和回复消息

这篇文章主要为大家详细介绍了java微信开发API第二步,获取消息和回复消息,感兴趣的小伙伴们可以参考一下

微信开发API如何获取和回复消息,下面就为大家进行介绍

一、说明
* 本示例根据微信开发文档:http://mp.weixin.qq.com/wiki/home/index.html最新版(4/3/2016 5:34:36 PM )进行开发演示。
* 编辑平台:myeclipse10.7+win32+jdk1.7+tomcat7.0 
* 服务器:阿里云 windows server 2008 64bits
* 平台要求:servlet使用注解方式,平台要求:j2ee6.0+、jdk6.0+、tomcat7.0+
* 演示更加注重于api解析。
* 为了便于测试说明,每个测试用例为独立,不依赖于其它方法。对于封装,不多加考虑。
* 演示尽可能按照API要求进行,目的:了解文档使用方式,达到举一反三的效果。
* 知识要求:牢固的java基础、了解http网络通信知识、对于javaweb有足够了解、json解析
* 在每篇文章结束会给出该部分演示源码。在分析完API之后,会以源码包的形式给出所有演示源码。
* 当前时间:4/3/2016 5:32:57 PM ,以该时间为准。

二、文档原文-消息管理(摘要)
 •文档地址:http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
 •消息管理
 ◦接收消息-接收普通消息
 ◦接收消息-接收事件推送
 ◦发送消息-被动回复消息
 ◦发送消息-被动回复时的加解密
 ◦发送消息-客服消息
 ◦发送消息-群发接口
 ◦发送消息-模板消息接口
 ◦发送消息-模板消息运营规范
 ◦获取公众号自动回复配置

 三、文档理解
•接收消息
◦文档这样解释:​当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
 ◦理解:微信服务器将用户发送的消息通过Post流的形式返回给req。当我们想要获取用户发送的消息时,可以通过req.getInputStream()获取。当然,我们可以根据文档上关于消息的返回的xml格式,进行必要的解析。
 ◦
实现:

/*
 * 该部分我们获取用户发送的信息,并且解析成的形式进行显示
 */
// 解析用户发送过来的信息
InputStream is = req.getInputStream();// 拿取请求流
// 将解析结果存储在HashMap中
Map map = new HashMap();
// 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】
Document document = null;
try {
 document = reader.read(is);
} catch (DocumentException e1) {
 // TODO Auto-generated catch block
 e1.printStackTrace();
}
// 得到xml根元素
Element root = document.getRootElement();
// 得到根元素的所有子节点
List elementList = root.elements();

// 遍历所有子节点
for (Element e : elementList)
 map.put(e.getName(), e.getText());

// 测试输出
Set keySet = map.keySet();
// 测试输出解析后用户发过来的信息
System.out.println(TAG + ":解析用户发送过来的信息开始");
for (String key : keySet) {
 System.out.println(key + ":" + map.get(key));
}
System.out.println(TAG + ":解析用户发送过来的信息结束"); 

•发送消息
◦文档这样解释:​当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。
 ◦理解:用户发送请求,会产生一个POST请求,我们可以通过Respone进行回复消息。但是,回复的内容有严格的格式要求,只有满足格式要求,微信服务器才会进行处理返回给用户。通过查看文档“消息管理”模块,我们可以看到微信中有各种各样的消息,每类消息都有自己特定的格式要求,我们必须按照要求才可以正常的给用户返回特定的信息。我们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造需要的参数。特别注意:参数区分大小写。
 ◦实现1-回复普通文本消息:

//实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式

// 第一步:按照回复文本信息构造需要的参数
TextMsg textMsg = new TextMsg();
textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
textMsg.setFromUserName(map.get("ToUserName"));
textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
textMsg.setMsgType("text");// 文本类型消息
textMsg.setContent("我是服务器回复给用户的信息");

// // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
XStream xStream = new XStream();
xStream.alias("xml", textMsg.getClass());
String textMsg2Xml = xStream.toXML(textMsg);
System.out.println(textMsg2Xml);

// // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
PrintWriter printWriter = resp.getWriter();
printWriter.print(textMsg2Xml);

 ◦实现2-回复图文消息:

//实例2,发送图文消息。请查看文档关于“回复图文消息”的xml格式

// 第一步:按照回复图文信息构造需要的参数
List
articles = new ArrayList
(); Article a = new Article(); a.setTitle("我是图片标题"); a.setUrl("www.baidu.com");// 该地址是点击图片跳转后 a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址 a.setDescription("我是图片的描述"); articles.add(a); PicAndTextMsg picAndTextMsg = new PicAndTextMsg(); picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反 picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型) picAndTextMsg.setMsgType("news");// 图文类型消息 picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】 XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户 PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml);

该部分所有操作源码,可以直接使用
 •CoreServlet.java(包括服务器接入、接收用户发送消息、回复普通文字消息、回复图文消息。需要第三方jar:dom4j、xstream)

package com.gist.servlet;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.gist.bean.Article;
import com.gist.bean.PicAndTextMsg;
import com.thoughtworks.xstream.XStream;

/**
 * @author 高远 邮箱:wgyscsf@163.com 博客 http://blog.csdn.net/wgyscsf
 *  编写时期 2016-4-3 下午4:34:05
 */
@WebServlet("/CoreServlet")
public class CoreServlet extends HttpServlet {
 private static final long serialVersiOnUID= 1L;
 String TAG = "CoreServlet";

 /*
 * 第二步:验证服务器地址的有效性 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,
 * GET请求携带四个参数:signature、timestamp、nonce、echostr
 * 开发者通过检验signature对请求进行校验(下面有校验方式)。 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,
 * 则接入生效, 成为开发者成功,否则接入失败。
 * 
 * 加密/校验流程如下: 1. 将token、timestamp、nonce三个参数进行字典序排序 2.
 * 将三个参数字符串拼接成一个字符串进行sha1加密 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
 */
 /*
 * 字典排序(lexicographical
 * order)是一种对于随机变量形成序列的排序方法。其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
 */
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {

 // 设置编码
 req.setCharacterEncoding("utf-8");
 resp.setContentType("html/text;charset=utf-8");
 resp.setCharacterEncoding("utf-8");
 // 获取输出流
 PrintWriter printWriter = resp.getWriter();

 // 设置一个全局的token,开发者自己设置。api这样解释:Token可由开发者可以任意填写,
 // 用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
 String token = "wgyscsf";
 // 根据api说明,获取上述四个参数
 String signature = req.getParameter("signature");
 String timestamp = req.getParameter("timestamp");
 String nOnce= req.getParameter("nonce");
 String echostr = req.getParameter("echostr");
 // // temp:临时打印,观看返回参数情况
 // System.out.println(TAG + ":signature:" + signature + ",timestamp:"
 // + timestamp + ",nonce:" + nonce + ",echostr:" + echostr);
 // 根据api所说的“加密/校验流程”进行接入。共计三步

 // 第一步:将token、timestamp、nonce三个参数进行字典序排序
 String[] parms = new String[] { token, timestamp, nonce };// 将需要字典序排列的字符串放到数组中
 Arrays.sort(parms);// 按照api要求进行字典序排序
 // 第二步:将三个参数字符串拼接成一个字符串进行sha1加密
 // 拼接字符串
 String parmsString = "";// 注意,此处不能=null。
 for (int i = 0; i " + signature);
 if (mParms.equals(signature)) {
  // System.out.println(TAG + ":" + mParms + "---->" + signature);
  printWriter.write(echostr);
 } else {
  // 接入失败,不用回写
  // System.out.println(TAG + "接入失败");
 }
 }

 /*
 * 查看api文档关于收发消息推送的消息格式基本一致。 如以下格式: 
 * 
 * 
 * 1348831860 
 * 
 * 1234567890123456  那么,我们就可以进行统一处理。
 */
 /*
 * 我们先获取输入流,看输入流里面的信息。通过测试打印输出流,我们可以看到每次用户请求,都会收到req请求,请求格式是xml格式,该信息在文档中有说明。
 */
 /*
 * 特别注意,req.getInputStream()只能获取一次,并且只能读取一次。如果想要多次读取,需要另外想办法。为了简单起见,
 * 我们只获取一次req.getInputStream(),不再打印输出流信息。直接打印解析后的信息。
 */
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
  throws ServletException, IOException {
 // 设置编码
 req.setCharacterEncoding("utf-8");
 resp.setContentType("html/text;charset=utf-8");
 resp.setCharacterEncoding("utf-8");

 /*
  * 该部分我们获取用户发送的信息,并且解析成的形式进行显示
  */
 // 解析用户发送过来的信息
 InputStream is = req.getInputStream();// 拿取请求流
 // 将解析结果存储在HashMap中
 Map map = new HashMap();
 // 解析xml,将获取到的返回结果xml进行解析成我们习惯的文字信息
 SAXReader reader = new SAXReader();// 第三方jar:dom4j【百度:saxreader解析xml】
 Document document = null;
 try {
  document = reader.read(is);
 } catch (DocumentException e1) {
  // TODO Auto-generated catch block
  e1.printStackTrace();
 }
 // 得到xml根元素
 Element root = document.getRootElement();
 // 得到根元素的所有子节点
 List elementList = root.elements();

 // 遍历所有子节点
 for (Element e : elementList)
  map.put(e.getName(), e.getText());

 // 测试输出
 Set keySet = map.keySet();
 // 测试输出解析后用户发过来的信息
 System.out.println(TAG + ":解析用户发送过来的信息开始");
 for (String key : keySet) {
  System.out.println(key + ":" + map.get(key));
 }
 System.out.println(TAG + ":解析用户发送过来的信息结束");

 /*
  * 该部分我们尝试按照文档的要求格式给用户回复文本信息、图文消息。重点:按照文档要求构造需要的参数。特别注意:参数区分大小写。
  */

 // //实例1:发送普通文本消息,请查看文档关于“回复文本消息”的xml格式
 //
 // // 第一步:按照回复文本信息构造需要的参数
 // TextMsg textMsg = new TextMsg();
 // textMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反
 // textMsg.setFromUserName(map.get("ToUserName"));
 // textMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型)
 // textMsg.setMsgType("text");// 文本类型消息
 // textMsg.setContent("我是服务器回复给用户的信息");
 //
 // // // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】
 // XStream xStream = new XStream();
 // xStream.alias("xml", textMsg.getClass());
 // String textMsg2Xml = xStream.toXML(textMsg);
 // System.out.println(textMsg2Xml);
 //
 // // // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户
 // PrintWriter printWriter = resp.getWriter();
 // printWriter.print(textMsg2Xml);

 // //实例2,发送图文消息。请查看文档关于“回复图文消息”的xml格式

 // 第一步:按照回复图文信息构造需要的参数
 List
articles = new ArrayList
(); Article a = new Article(); a.setTitle("我是图片标题"); a.setUrl("www.baidu.com");// 该地址是点击图片跳转后 a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// 该地址是一个有效的图片地址 a.setDescription("我是图片的描述"); articles.add(a); PicAndTextMsg picAndTextMsg = new PicAndTextMsg(); picAndTextMsg.setToUserName(map.get("FromUserName"));// 发送和接收信息“User”刚好相反 picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// 消息创建时间 (整型) picAndTextMsg.setMsgType("news");// 图文类型消息 picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // 第二步,将构造的信息转化为微信识别的xml格式【百度:xstream bean转xml】 XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // 第三步,发送xml的格式信息给微信服务器,服务器转发给用户 PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml); } }

 •TestMsg.java(普通文字消息bean)

package com.gist.bean;

/**
 * @author 高远 邮箱:wgyscsf@163.com 博客 http://blog.csdn.net/wgyscsf
 *  编写时期 2016-4-4 下午2:09:27
 */
public class TextMsg {
 private String ToUserName;
 private String FromUserName;
 private long CreateTime;
 private String MsgType;

 @Override
 public String toString() {
 return "TextMsg [ToUserName=" + ToUserName + ", FromUserName="
  + FromUserName + ", CreateTime=" + CreateTime + ", MsgType="
  + MsgType + ", COntent=" + Content + "]";
 }

 private String Content;

 public TextMsg(String toUserName, String fromUserName, long createTime,
  String msgType, String content) {
 super();
 ToUserName = toUserName;
 FromUserName = fromUserName;
 CreateTime = createTime;
 MsgType = msgType;
 COntent= content;
 }

 public TextMsg() {
 super();
 }

 public String getToUserName() {
 return ToUserName;
 }

 public void setToUserName(String toUserName) {
 ToUserName = toUserName;
 }

 public String getFromUserName() {
 return FromUserName;
 }

 public void setFromUserName(String fromUserName) {
 FromUserName = fromUserName;
 }

 public long getCreateTime() {
 return CreateTime;
 }

 public void setCreateTime(long createTime) {
 CreateTime = createTime;
 }

 public String getMsgType() {
 return MsgType;
 }

 public void setMsgType(String msgType) {
 MsgType = msgType;
 }

 public String getContent() {
 return Content;
 }

 public void setContent(String content) {
 COntent= content;
 }
}

 •Article.java(图文消息内部Article bean)

package com.gist.bean;

/**
 * @author 高远 邮箱:wgyscsf@163.com 博客 http://blog.csdn.net/wgyscsf
 *  编写时期 2016-4-4 下午2:47:08
 */
public class Article {
 private String Title;

 @Override
 public String toString() {
 return "item [Title=" + Title + ", Description=" + Description
  + ", PicUrl=" + PicUrl + ", Url=" + Url + "]";
 }

 public String getTitle() {
 return Title;
 }

 public void setTitle(String title) {
 Title = title;
 }

 public String getDescription() {
 return Description;
 }

 public void setDescription(String description) {
 Description = description;
 }

 public String getPicUrl() {
 return PicUrl;
 }

 public void setPicUrl(String picUrl) {
 PicUrl = picUrl;
 }

 public String getUrl() {
 return Url;
 }

 public void setUrl(String url) {
 Url = url;
 }

 private String Description;
 private String PicUrl;
 private String Url;

}

 •PicAndTextMsg.java(图文消息 bean)

package com.gist.bean;

import java.util.List;

/**
 * @author 高远 邮箱:wgyscsf@163.com 博客 http://blog.csdn.net/wgyscsf
 *  编写时期 2016-4-4 下午2:47:08
 */
public class PicAndTextMsg {
 private String ToUserName;
 private String FromUserName;
 private long CreateTime;
 private String MsgType;
 private int ArticleCount;
 private List
Articles; @Override public String toString() { return "PicAndTextMsg [ToUserName=" + ToUserName + ", FromUserName=" + FromUserName + ", CreateTime=" + CreateTime + ", MsgType=" + MsgType + ", ArticleCount=" + ArticleCount + ", Articles=" + Articles + "]"; } public String getToUserName() { return ToUserName; } public void setToUserName(String toUserName) { ToUserName = toUserName; } public String getFromUserName() { return FromUserName; } public void setFromUserName(String fromUserName) { FromUserName = fromUserName; } public long getCreateTime() { return CreateTime; } public void setCreateTime(long createTime) { CreateTime = createTime; } public String getMsgType() { return MsgType; } public void setMsgType(String msgType) { MsgType = msgType; } public int getArticleCount() { return ArticleCount; } public void setArticleCount(int articleCount) { ArticleCount = articleCount; } public List
getArticles() { return Articles; } public void setArticles(List
articles) { Articles = articles; } }

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


推荐阅读
  • 禁止程序接收鼠标事件的工具_VNC Viewer for Mac(远程桌面工具)免费版
    VNCViewerforMac是一款运行在Mac平台上的远程桌面工具,vncviewermac版可以帮助您使用Mac的键盘和鼠标来控制远程计算机,操作简 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 如何去除Win7快捷方式的箭头
    本文介绍了如何去除Win7快捷方式的箭头的方法,通过生成一个透明的ico图标并将其命名为Empty.ico,将图标复制到windows目录下,并导入注册表,即可去除箭头。这样做可以改善默认快捷方式的外观,提升桌面整洁度。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Centos7.6安装Gitlab教程及注意事项
    本文介绍了在Centos7.6系统下安装Gitlab的详细教程,并提供了一些注意事项。教程包括查看系统版本、安装必要的软件包、配置防火墙等步骤。同时,还强调了使用阿里云服务器时的特殊配置需求,以及建议至少4GB的可用RAM来运行GitLab。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • PDF内容编辑的两种小方法,你知道怎么操作吗?
    本文介绍了两种PDF内容编辑的方法:迅捷PDF编辑器和Adobe Acrobat DC。使用迅捷PDF编辑器,用户可以通过选择需要更改的文字内容并设置字体形式、大小和颜色来编辑PDF文件。而使用Adobe Acrobat DC,则可以通过在软件中点击编辑来编辑PDF文件。PDF文件的编辑可以帮助办公人员进行文件内容的修改和定制。 ... [详细]
  • 小程序自动授权和手动接入的方式及操作步骤
    本文介绍了小程序支持的两种接入方式:自动授权和手动接入,并详细说明了它们的操作步骤。同时还介绍了如何在两种方式之间切换,以及手动接入后如何下载代码包和提交审核。 ... [详细]
  • 分享css中提升优先级属性!important的用法总结
    web前端|css教程css!importantweb前端-css教程本文分享css中提升优先级属性!important的用法总结微信门店展示源码,vscode如何管理站点,ubu ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
author-avatar
手机用户2502921293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有