微信公众平台PHP开发全教程
微信公众平台分为两种模式:

- 订阅号:主要用于信息传递和内容创作,功能相对简单。
- 服务号:提供更多服务和API接口,如微信支付、用户信息获取等,适合企业和组织。
本教程主要面向 服务号 的开发,因为其功能更全面,但大部分基础消息处理逻辑对订阅号同样适用。
第一部分:准备工作
在开始编码之前,你需要完成以下准备工作:
注册公众号
- 访问 微信公众平台官网。
- 使用一个未注册过公众号的邮箱进行注册。
- 根据提示完成身份认证(个人或企业),选择订阅号或服务号。
- 注意:个人主体只能注册订阅号,且部分高级接口(如微信支付)无法使用,企业主体可以注册服务号,功能更全。
获取开发者凭证
- 登录你的公众号后台。
- 在左侧菜单栏找到 “设置与开发” -> “基本配置”。
- 在这里你可以找到:
- AppID (应用ID):公众号的唯一标识。
- AppSecret (应用密钥):用于获取 Access Token 的密钥,请务必保密!
服务器配置(接入)
这是最关键的一步,用于验证你的服务器是否有效。
- 在 “基本配置” 页面,找到 “服务器配置”。
- 点击 “修改配置”。
- 你需要填写以下信息:
- URL (服务器地址):你的服务器上一个能够接收 HTTP POST 请求的 PHP 文件的完整地址。
http://yourdomain.com/wechat.php。 - Token (令牌):可以任意填写,如
mywechat_token,用于后续验证请求的合法性。 - EncodingAESKey (消息加解密密钥):可以随机生成,用于安全地接收和发送消息。
- 消息加解密方式:选择 “安全模式” 或 “兼容模式”,安全模式要求消息内容都经过加密,兼容模式则明文和加密消息均可,新手建议先选择 “明文模式”,调试成功后再切换到安全模式。
- URL (服务器地址):你的服务器上一个能够接收 HTTP POST 请求的 PHP 文件的完整地址。
第二部分:接入验证
当你填写完服务器配置并提交后,微信服务器会向你的 URL 发送一个 GET 请求,以验证你的服务器地址,你需要编写 PHP 代码来响应这个请求。

验证逻辑
- 你的服务器收到 GET 请求,会带上四个参数:
signature,timestamp,nonce,echostr。 - 你需要将
Token(你在后台填写的)、timestamp、nonce三个参数进行字典序排序。 - 将排序后的三个参数字符串拼接成一个字符串,并进行
SHA1加密。 - 将加密后的字符串与请求中的
signature进行对比。 - 如果一致,说明请求来自微信,原样返回
echostr参数内容,接入成功。
PHP 代码实现 (wechat.php)
<?php
/**
* 微信公众号接入验证
*/
// 1. 获取微信推送过来的数据
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$echostr = $_GET["echostr"];
// 2. 你在后台填写的 Token
$token = "mywechat_token"; // 务必与后台配置的 Token 一致
// 3. 将 token, timestamp, nonce 三个参数进行字典序排序
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
// 4. 将三个参数字符串拼接成一个字符串并进行 SHA1 加密
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
// 5. 开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信
if ($tmpStr == $signature && $echostr) {
// 如果是验证请求,则返回 echostr
echo $echostr;
exit;
} else {
// 如果不是验证请求,则可能是正常的消息推送
// ... 这里后面会处理消息 ...
}
?>
操作步骤:
- 将上面的代码保存为
wechat.php,并上传到你的服务器(确保 PHP 环境已配置好)。 - 在服务器上确保
http://yourdomain.com/wechat.php可以通过浏览器访问。 - 回到微信后台,点击 “提交”。
- 如果提示成功,恭喜你,服务器已经成功接入!
第三部分:接收与回复消息
接入成功后,当用户与你的公众号进行交互(如发送消息、点击菜单等),微信服务器会向你的 wechat.php 发送一个 POST 请求,你需要解析这个请求,并根据内容做出回复。
消息格式
微信推送过来的消息是 XML 格式,不同类型的消息,XML 结构略有不同。
文本消息示例:
<xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDATA[fromUser]]></FromUserName> <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[this is a test]]></Content> <MsgId>1234567890123456</MsgId> </xml>
字段说明:
ToUserName:开发者微信号(你的公众号ID)。FromUserName:发送方帐号(用户的 OpenID)。CreateTime:消息创建时间 (时间戳)。MsgType:消息类型 (text,image,event等)。Content(文本消息特有)。MsgId:消息ID。
PHP 代码实现
我们需要修改 wechat.php,使其能够处理 POST 请求。
<?php
/**
* 微信公众号PHP开发
*/
// 开启错误报告,方便调试
error_reporting(E_ALL);
ini_set('display_errors', 1);
// 1. 接入验证 (GET请求)
if (isset($_GET['echostr'])) {
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = "mywechat_token";
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode($tmpArr);
$tmpStr = sha1($tmpStr);
if ($tmpStr == $signature) {
echo $_GET["echostr"];
exit;
}
}
// 2. 接收消息 (POST请求)
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// 获取POST过来的XML数据
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
// 如果没有 raw post data,尝试使用 php://input
if (empty($postStr)) {
$postStr = file_get_contents('php://input');
}
// 空判断
if (!empty($postStr)) {
// 将XML解析成PHP对象
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$msgType = $postObj->MsgType;
// 根据消息类型处理
if ($msgType == 'text') {
// 回复文本消息
if (!empty($keyword)) {
$contentStr = "你发送的是: " . $keyword;
} else {
$contentStr = "请输入文字";
}
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, time(), $contentStr);
echo $resultStr;
} else if ($msgType == 'event') {
// 处理事件推送,比如关注/取消关注
if ($postObj->Event == 'subscribe') {
// 用户关注事件
$welcomeMsg = "欢迎关注我们的公众号!";
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, time(), $welcomeMsg);
echo $resultStr;
}
}
} else {
echo "Not Weixin Server Request!";
}
}
?>
代码解析:
- 我们同时处理了
GET(接入验证)和POST(消息接收)请求。 $GLOBALS["HTTP_RAW_POST_DATA"]或file_get_contents('php://input')用于获取原始的 POST 数据,因为微信发送的是 XML,而不是表单数据。simplexml_load_string()是 PHP 内置的函数,用于将 XML 字符串解析成对象,LIBXML_NOCDATA选项可以处理<![CDATA[]]>- 我们判断了
MsgType,如果是text,则回复一条文本消息。- 回复消息也必须是特定的 XML 格式,我们使用
sprintf()来填充模板。- 我们还增加了对
event消息类型的处理,特别是subscribe(关注)事件,这是实现欢迎语的关键。- 我们判断了
你可以部署更新后的代码,然后用你的微信关注公众号,发送任意文字,你应该就能收到自动回复了!
第四部分:高级功能
Access Token (访问令牌)
调用微信绝大多数高级接口(如获取用户信息、发送模板消息等)都需要一个 access_token。
- 特点:
- 有效期为 2小时,过期后需要重新获取。
- 全局唯一,每个公众号有自己的 token。
- 每天获取次数有限制(目前为2000次)。
- 获取方式:
向
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET发送 GET 请求。 - PHP 实现:
建议将获取和缓存
access_token的逻辑封装成一个函数,并使用文件或数据库进行缓存,避免频繁请求微信服务器。
function getAccessToken($appId, $appSecret) {
// 尝试从缓存中获取
$cacheFile = 'access_token_' . $appId . '.cache';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 7000) { // 7000秒有效期,留有余地
return file_get_contents($cacheFile);
}
// 如果缓存不存在或已过期,则向微信服务器请求
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
$res = json_decode(file_get_contents($url));
$accessToken = $res->access_token;
// 将新的token写入缓存
file_put_contents($cacheFile, $accessToken);
return $accessToken;
}
// 使用示例
$accessToken = getAccessToken('你的AppID', '你的AppSecret');
获取用户基本信息
通过用户的 OpenID,可以获取其昵称、头像、性别和地区等信息。
-
接口地址:
https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN -
PHP 实现:
function getUserInfo($accessToken, $openId) { $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$accessToken}&openid={$openId}&lang=zh_CN"; $userInfo = json_decode(file_get_contents($url)); return $userInfo; } // 使用示例 (假设 $fromUsername 是用户的 OpenID) // $user = getUserInfo($accessToken, $fromUsername); // echo "昵称: " . $user->nickname;
发送模板消息
模板消息用于发送重要的服务通知,如订单确认、物流更新等。
-
流程:
- 在公众号后台“模板消息”中选择一个模板并获取其
template_id。 - 构造符合规范的 JSON 数据。
- 调用接口发送。
- 在公众号后台“模板消息”中选择一个模板并获取其
-
接口地址:
https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN -
PHP 实现:
function sendTemplateMessage($accessToken, $openId, $templateId, $data, $url = '') { $postUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={$accessToken}"; $post_data = array( "touser" => $openId, "template_id" => $templateId, "url" => $url, "data" => $data ); $post_data = json_encode($post_data); $res = http_post($postUrl, $post_data); return json_decode($res); } // 辅助函数:发送POST请求 function http_post($url, $data) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $tmpInfo = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $tmpInfo; } // 使用示例 // $templateId = 'your_template_id'; // $data = array( // 'first' => array('value' => '您的订单已支付成功', 'color' => '#173177'), // 'keyword1' => array('value' => '202512121234', 'color' => '#173177'), // 'keyword2' => array('value' => '¥99.00', 'color' => '#173177'), // 'remark' => array('value' => '感谢您的购买!', 'color' => '#173177') // ); // sendTemplateMessage($accessToken, $fromUsername, $templateId, $data);
第五部分:推荐工具与框架
- 调试工具:
- 微信Web开发者工具:官方提供的调试工具,可以模拟用户发送各种消息,查看服务器返回的XML数据,非常方便。
- Postman / curl:用于手动测试API接口,如获取
access_token、发送模板消息等。
- PHP SDK:
手动处理所有API非常繁琐,社区里有很多优秀的第三方SDK可以大大简化开发工作,
- EasyWeChat:目前最流行、功能最全面的微信非官方SDK,支持公众号、小程序、企业微信等,文档齐全,社区活跃。强烈推荐新手使用!
- overtrue/wechat:另一个优秀的SDK,简洁易用。
使用 EasyWeChat 示例(获取用户信息):
use EasyWeChat\Factory;
$config = [
'app_id' => 'your-app-id',
'app_secret' => 'your-app-secret',
// ...
];
$app = Factory::officialAccount($config);
$user = $app->user->get($openId); // $openId 是用户的 OpenID
echo $user->nickname;
echo $user->avatar;
使用SDK后,你只需要关心业务逻辑,而不用去拼接那些复杂的XML和JSON数据。
- 准备工作:注册公众号,获取
AppID和AppSecret。 - 服务器配置:填写
URL,Token,完成接入验证。 - 消息处理:编写
wechat.php,解析微信的 XML POST 数据,并根据内容回复 XML 格式的消息。 - 高级功能:学习使用
access_token,调用各种API接口(如获取用户信息、发送模板消息)。 - 进阶:使用成熟的SDK(如EasyWeChat)来提高开发效率。
这份教程为你打下了坚实的基础,微信开发还有很多细节,如网页授权、微信支付、JSSDK等,都可以在此基础上进行学习和探索,祝你开发顺利!
