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

Android Studio请求PHP接口时json_decode()返回NULL问题排查

问题根因
  • 两端表现不一致的核心原因是:Chrome发起请求时会自动完成参数URL编码、设置标准表单请求头,PHP可以正常解析参数;而原生HttpURLConnection默认不会做这些处理,直接拼接JSON传参会破坏POST表单结构,导致PHP拿到的参数不是完整合法的JSON串,json_decode自然返回NULL
  • 现有Android代码存在3个明确问题:
    • 直接拼接未编码的JSON字符串:JSON自带的"、{}、:、空格、&等特殊字符会截断参数,导致$_POST['attrArr']拿到的是残缺内容
    • 未设置POST表单对应的Content-Type请求头,PHP无法按标准表单格式解析传入的请求体
    • 提前调用httpURLConnection.connect(),在连接建立后再配置请求参数不会生效
修复方案

1. 核心修复:修改Android端请求逻辑

替换doInBackground方法内的代码,重点处理参数编码、请求头配置、连接逻辑:

@Override
protected String doInBackground(String... params) {
    String attrArr = params[1];
    String serverURL = params[0];
    // 对JSON参数做URL编码,转义所有特殊字符,避免破坏表单结构
    String postParameters = "attrArr=" + URLEncoder.encode(attrArr, "UTF-8");

    try {
        URL url = new URL(serverURL);
        HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

        httpURLConnection.setReadTimeout(5000);
        httpURLConnection.setConnectTimeout(5000);
        httpURLConnection.setRequestMethod("POST");
        // 设置标准表单请求头,指定UTF-8编码
        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        httpURLConnection.setDoOutput(true);
        // 移除提前调用的connect(),获取输出流时会自动建立连接,所有配置都会生效

        OutputStream outputStream = httpURLConnection.getOutputStream();
        outputStream.write(postParameters.getBytes("UTF-8"));
        outputStream.flush();
        outputStream.close();

        int responseStatusCode = httpURLConnection.getResponseCode();
        Log.d(TAG, "POST response code - " + responseStatusCode);

        InputStream inputStream;
        if(responseStatusCode == HttpURLConnection.HTTP_OK) {
            inputStream = httpURLConnection.getInputStream();
        } else {
            inputStream = httpURLConnection.getErrorStream();
        }

        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

        StringBuilder sb = new StringBuilder();
        String line;
        while((line = bufferedReader.readLine()) != null){
            sb.append(line);
        }
        bufferedReader.close();
        return sb.toString();

    } catch (Exception e) {
        Log.d(TAG, "InsertData: Error ", e);
        return "Error: " + e.getMessage();
    }
}

注意:PHP接收$_POST参数时会自动对URL编码的内容做解码,拿到的是原始完整JSON串,不需要额外调用stripslashes()处理,反而可能破坏JSON结构。

2. PHP端加容错与调试逻辑

如果修改Android端后仍解析失败,先在PHP端增加JSON错误校验,快速定位问题:

<?php
$attrArr = isset($_POST['attrArr']) ? trim($_POST['attrArr']) : '';
$data = json_decode($attrArr, true);
// 校验JSON解析结果
if (json_last_error() !== JSON_ERROR_NONE) {
    echo "解析失败,错误原因:" . json_last_error_msg();
    echo " 接收到的参数内容:" . $attrArr;
    exit;
}
// 后续业务逻辑
echo "gettype($data): " . gettype($data);
?>

常见解析失败场景:

  • 参数被截断:未做URL编码时,JSON里如果包含&字符,PHP会把它识别为参数分隔符,导致attrArr只拿到&之前的残缺内容
  • 多余转义字符:仅当PHP版本低于5.4且开启了魔术引号时才需要用stripslashes(),新版本PHP默认关闭该配置,强行调用会把合法JSON转成非法格式
  • 首尾不可见字符:trim()可以去掉参数首尾的BOM头、换行、空格等不可见字符,避免解析失败
验证步骤
  • 重新运行Android端发起请求,正常情况下PHP端会返回gettype($data): array
  • 如果仍报错,根据PHP返回的错误原因,对比接收到的参数内容和Android端resultObject.toString()的输出是否完全一致,排查是否存在内容截断、多余字符问题

内容的提问来源于stack exchange,提问作者helpmeplz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 19:03:41