本文目录导读:

在PHP中开发微信小程序获取手机号,主要涉及微信小程序前端和PHP后端的配合,以下是完整的实现流程、代码示例及注意事项。
整体流程
- 前端(小程序):用户点击按钮,触发
getPhoneNumber事件,微信返回code(动态令牌)。 - 前端:将
code发送到你的 PHP 后端。 - 后端(PHP):使用
code+appid+secret调用微信接口,换取手机号信息。 - 后端:将手机号返回给前端。
前端(小程序端)代码
<!-- 页面 wxml --> <button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber">获取手机号</button>
// 页面 js
Page({
getPhoneNumber(e) {
if (e.detail.errMsg === 'getPhoneNumber:ok') {
// 拿到动态令牌 code
const code = e.detail.code;
// 发送到后端
wx.request({
url: 'https://yourdomain.com/api/getPhone',
method: 'POST',
data: { code: code },
success(res) {
console.log('手机号:', res.data.phoneNumber);
}
});
} else {
console.log('用户取消授权');
}
}
});
后端(PHP)核心代码
获取 access_token
function getAccessToken($appid, $secret) {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
$result = file_get_contents($url);
$data = json_decode($result, true);
return $data['access_token'] ?? null;
}
使用 code 换取手机号
function getPhoneNumber($code, $access_token) {
$url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token={$access_token}";
$data = json_encode(['code' => $code]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
完整接口示例
<?php
// 接收前端请求
$input = json_decode(file_get_contents('php://input'), true);
$code = $input['code'] ?? '';
// 配置你自己的 appid 和 secret
$appid = '你的小程序appid';
$secret = '你的小程序secret';
// 获取 access_token
$access_token = getAccessToken($appid, $secret);
if (!$access_token) {
echo json_encode(['code' => 500, 'msg' => '获取access_token失败']);
exit;
}
// 获取手机号
$result = getPhoneNumber($code, $access_token);
if ($result['errcode'] == 0) {
// 成功
$phoneInfo = $result['phone_info'];
echo json_encode([
'code' => 200,
'phoneNumber' => $phoneInfo['purePhoneNumber'], // 纯手机号(不带区号)
'countryCode' => $phoneInfo['countryCode'], // 国家区号
'phoneNumberFull' => $phoneInfo['phoneNumber'] // 完整手机号(带区号)
]);
} else {
echo json_encode([
'code' => $result['errcode'],
'msg' => $result['errmsg']
]);
}
?>
注意事项
需要企业认证
- 个人主体的小程序不支持获取手机号功能。
- 必须是企业、政府、媒体、其他组织主体。
接口权限
- 需要在小程序后台 “开发管理” → “接口设置” 中申请开通“获取手机号”权限。
收费说明
- 自2023年起,微信对获取手机号接口进行收费:每次成功调用扣除 0.03 元。
安全性
- access_token 建议缓存,不要每次都请求(有效期为7200秒)。
- 后端需校验
code的有效性,防止恶意请求。
缓存 access_token 示例
function getAccessTokenWithCache($appid, $secret) {
$cache_file = 'access_token.json';
if (file_exists($cache_file)) {
$data = json_decode(file_get_contents($cache_file), true);
if ($data['expire_time'] > time()) {
return $data['access_token'];
}
}
$access_token = getAccessToken($appid, $secret);
file_put_contents($cache_file, json_encode([
'access_token' => $access_token,
'expire_time' => time() + 7200 - 200 // 提前200秒过期,留余量
]));
return $access_token;
}
前端获取成功后的处理
wx.request({
url: 'https://yourdomain.com/api/getPhone',
method: 'POST',
data: { code: code },
success(res) {
if (res.data.code === 200) {
// 获取手机号成功
const phone = res.data.phoneNumber;
// 存储或使用
wx.setStorageSync('phone', phone);
console.log('用户手机号:', phone);
} else {
wx.showToast({
title: res.data.msg,
icon: 'none'
});
}
},
fail(err) {
console.error('请求失败:', err);
}
});
常见错误排查
| 错误码 | 说明 | 解决办法 |
|---|---|---|
| 40029 | code 无效 | 确保 code 未过期(5分钟内有效),且只使用一次 |
| 45009 | 接口调用超过限制 | 控制调用频率 |
| 48001 | api 功能未授权 | 在小程序后台申请开通权限 |
| 61003 | 手机号获取失败 | 用户未绑定手机号或已取消授权 |
- 关键点:前端拿
code→ 后端用code + appid + secret换手机号。 - 限制:需要企业主体、付费、开通接口权限。
- 安全:
access_token必须服务器端保存,不能下发到前端。
如果你只是需要获取用户手机号用于登录或绑定,建议结合短信验证码做双重验证,这样更安全。