PHP无法直接获取微信小程序wx.request的JSON数据,因默认content-type为application/json时$_POST为空,需用file_get_contents('php://input')读取并json_decode解析。

PHP 无法直接拿到微信小程序 wx.request 的 JSON 数据?
不是 PHP 有问题,是微信小程序默认把数据以 application/json 格式发过来,而 PHP 的 $_POST 只自动解析 application/x-www-form-urlencoded 和 multipart/form-data。所以你打印 $_POST 是空的,$_REQUEST 也是空的——这很常见,别急着改小程序端。
- 先确认小程序是否用了
header: { 'content-type': 'application/json' } - 如果用了,PHP 就不会填充
$_POST,必须手动读取原始请求体 - 用
file_get_contents('php://input')拿到原始 JSON 字符串,再用json_decode()解析 - 注意:
php://input只能读一次,且不能用于enctype="multipart/form-data"请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);
if (json_last_error() !== JSON_ERROR_NONE) {
http_response_code(400);
echo json_encode(['error' => 'Invalid JSON']);
exit;
}
// 此时 $data 就是你小程序传来的对象
$openid = $data['openid'] ?? '';
$score = $data['score'] ?? 0;
}
小程序传的是表单格式(application/x-www-form-urlencoded),但 PHP 还是收不到?
这种情况通常是前端没设对 content-type,或后端被 Nginx / Apache 重写规则干扰了。微信小程序默认不带 content-type,此时浏览器(或微信客户端)会按空值处理,部分服务器可能丢弃 body。
- 小程序端务必显式设置:
header: { 'content-type': 'application/x-www-form-urlencoded' } - 发送时用
URLSearchParams或拼接字符串,例如:new URLSearchParams({ openid: 'xxx', score: '100' }).toString() - PHP 端就能直接用
$_POST['openid']—— 但注意:如果 Nginx 配置了client_max_body_size过小,或启用了某些安全模块(如 ModSecurity),也可能拦截 POST 数据 - 调试时加一句:
error_log(print_r($_SERVER, true), 3, '/tmp/php_post.log');查看原始请求头
如何安全验证微信小程序的请求来源?
仅靠接收数据不够,必须校验是否真的来自你的小程序。最可靠的方式是:小程序在调用 wx.login 后获取 code,传给 PHP;PHP 拿 code + appid + appsecret 向微信接口换 session_key 和 openid,再用这个 session_key 解密小程序传来的加密数据(如用户信息)。
- 不要信任前端传来的
openid,它可被伪造;应以微信接口返回的为准 - 解密用户敏感数据(如手机号)必须用
openssl_decrypt+ 微信返回的session_key,且需补全 PKCS#7 填充 - PHP 中推荐用
base64_decode($encryptedData)再解密,别直接传 base64 字符串进openssl_decrypt - 微信登录凭证
code5 分钟内有效,且只能使用一次;PHP 收到后应立即调用微信接口https://api.weixin.qq.com/sns/jscode2session
PHP 接收 POST 数据时常见的 400 / 500 错误怎么排查?
错误本身不指向具体原因,得看日志和请求细节。400 多半是 JSON 格式错、编码问题或超长;500 往往是 PHP 解析失败、内存不足或 OpenSSL 扩展未启用。
立即学习“PHP免费学习笔记(深入)”;
- 检查 PHP 错误日志:
tail -f /var/log/php_errors.log(路径依环境而定) - 确认
post_max_size和max_input_vars足够大(尤其传大量字段时) - 如果用了
json_decode但没检查json_last_error(),出错会静默失败,建议统一包装成函数 - 微信开发者工具里开启“不校验合法域名”只是开发用,真机调试必须配好 HTTPS 和合法域名,否则请求根本发不出去











