You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP如何解析urlencode格式webhook内容取值并更新数据库

问题根因

代码无法获取参数的核心错误是用json_decode()解析URL编码格式的表单数据:你收到的webhook推送是标准的application/x-www-form-urlencoded格式(即key=value&key2=value2的URL编码结构),不是JSON格式,json_decode()处理这类内容会返回null,自然读不到任何字段值。
另外提前手动调用urldecode()处理原始输入是多余操作,后续解析函数会自动完成URL解码,手动提前解码反而可能在参数值包含&、=这类特殊字符时出现解析错误。

修复方案

直接使用PHP内置的parse_str()函数解析原始POST输入即可,该函数会自动完成URL解码,将所有参数解析为关联数组,不需要额外做转义处理。
修正后的完整代码如下:

<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    require_once 'dbcon/v20/dbcon.php';

    // 读取原始POST输入,无需提前做urldecode处理
    $rawInput = file_get_contents("php://input");
    // 解析urlencoded格式内容为关联数组
    parse_str($rawInput, $evt);

    // 基础参数校验,避免缺字段时抛出PHP警告
    if (!isset($evt['Status'], $evt['MsgId'], $evt['remoteid'])) {
        http_response_code(400);
        exit("Invalid request payload");
    }

    http_response_code(200);

    switch ($evt['Status']) {
        case 0:
            // waiting 待发送状态,可按需补充业务逻辑
            break;

        case 1:
            // in progress 发送中状态,可按需补充业务逻辑
            break;

        case 2:
            // sent 已发送
            $msgid = $evt['MsgId'];
            $sentdate = $evt['SendDateTime'];
            $remoteid = $evt['remoteid'];
            $status = "Sent";

            $uph = $mydbcon->prepare("UPDATE sms_send SET sent_date=?, status=? WHERE ticket=? AND remoteid=?");
            $uph->bind_param('ssss', $sentdate, $status, $msgid, $remoteid);
            $uph->execute(); 
            $uph->close(); // 释放预处理句柄,避免资源浪费
            break;

        case 3:
            // delivered 已送达
            $msgid = $evt['MsgId'];
            $sentdate = $evt['SendDateTime'];
            $deliverydate = $evt['DeliveryDateTime'] ?? ''; // 兼容字段为空的情况
            $remoteid = $evt['remoteid'];
            $status = "Delivered";
            
            $uph = $mydbcon->prepare("UPDATE sms_send SET sent_date=?, delivery_date=?, status=? WHERE ticket=? AND remoteid=?");
            $uph->bind_param('sssss', $sentdate, $deliverydate, $status, $msgid, $remoteid);
            $uph->execute();
            $uph->close();
            break;

        case 4:
            // refused 发送被拒,可按需补充业务逻辑
            break;

        case 6:
            // not delivered 未送达,可按需补充业务逻辑
            break;
    }

    exit();
}
?>
补充说明
  • 对于标准的application/x-www-form-urlencoded格式POST请求,你也可以直接通过$_POST全局变量获取对应参数,PHP会自动完成解析;手动读取php://input后用parse_str解析的方式兼容性更强,不受服务端特殊配置影响。
  • 调试阶段可以在解析完参数后加file_put_contents("test.txt", print_r($evt, true));,将解析后的完整数组写入文件,确认所有字段都能正常获取,调试完成后删除该行即可。
  • 数据库预处理语句执行完成后建议调用close()释放句柄,减少数据库连接资源占用。

内容的提问来源于stack exchange,提问作者Louis Web Solutions

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 05:49:18