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

Android Studio中Retrofit2更新MySQL行异常:请求成功但数据未更新

问题分析与解决方案

你遇到的核心问题有几个,咱们一个个拆解解决:

1. 请求方法不匹配 + 参数获取逻辑错误

你的Retrofit接口用的是@PUT请求,但PHP脚本只处理POST方法;而且你通过@Body传递JSON格式的Test对象,PHP里却试图用$_POST来取参数——这俩完全不兼容,导致PHP根本拿不到你传的name、age,自然没法更新数据库。

2. PHP数据库操作逻辑混乱

你的PHP脚本里还有明显的逻辑bug:

  • mysqli_fetch_array(mysqli_query($db, $sql)):UPDATE语句执行后返回的是布尔值(成功/失败),不是结果集,用mysqli_fetch_array处理纯纯错误
  • if (mysqli_query($check)):这里的$check已经是mysqli_fetch_array的结果,再传给mysqli_query完全逻辑混乱
  • 直接把用户输入拼进SQL语句,存在严重的SQL注入风险

修正后的完整解决方案

第一步:确认Retrofit接口与实体类(保持RESTful风格)

你的接口写法没问题,但要确保Test类能被正确序列化为JSON:

public interface JsonPlaceHolderApiTest { 
    @PUT("update.php/{id}") 
    Call<Test> putTest(@Path("id") int id, @Body Test test); 
}

Test类要添加序列化注解,确保字段名和JSON键对应:

public class Test {
    @SerializedName("name")
    private String name;
    @SerializedName("age")
    private String age;

    public Test(String name, String age) {
        this.name = name;
        this.age = age;
    }

    // 记得添加getter/setter,或者让字段public,方便Gson序列化
}

第二步:彻底修复PHP脚本

下面是修正后的PHP代码,解决了请求方法兼容、参数获取、逻辑错误和SQL注入问题:

<?php
// 初始化响应数组
$response = ["success" => false, "message" => ""];

// 兼容PUT和POST请求
if ($_SERVER['REQUEST_METHOD'] === 'PUT' || $_SERVER['REQUEST_METHOD'] === 'POST') {
    // 读取请求体的JSON数据
    $input = file_get_contents('php://input');
    $data = json_decode($input, true);

    // 从URL路径获取id(因为用了@Path("id"),id在URL参数里)
    $id = $_GET['id'] ?? null;
    $name = $data['name'] ?? null;
    $age = $data['age'] ?? null;

    // 参数校验
    if (!$id || !$name || !$age) {
        $response["message"] = "缺少必要参数";
        echo json_encode($response);
        exit;
    }

    require_once 'db_config.php';
    mysqli_set_charset($db, 'utf8');

    // 使用预处理语句防止SQL注入
    $sql = "UPDATE `test` SET name=?, age=? WHERE id=?";
    $stmt = mysqli_prepare($db, $sql);
    mysqli_stmt_bind_param($stmt, "ssi", $name, $age, $id);

    // 执行更新并判断结果
    if (mysqli_stmt_execute($stmt)) {
        // 检查是否有行被更新(避免id不存在的情况)
        if (mysqli_stmt_affected_rows($stmt) > 0) {
            $response["success"] = true;
            $response["message"] = "更新成功";
        } else {
            $response["message"] = "未找到对应ID的记录,无更新操作";
        }
    } else {
        $response["message"] = "更新失败: " . mysqli_error($db);
    }

    mysqli_stmt_close($stmt);
    mysqli_close($db);
} else {
    $response["message"] = "不支持的请求方法,请使用PUT或POST";
}

echo json_encode($response);
?>

第三步:优化Android端回调处理

把Toast改成显示更具体的响应内容,方便调试:

private void updateTest(){ 
    Test test = new Test ("updated_name", "updated_age"); 
    Call<Test> call = jsonPlaceHolderApiTest.putTest(3, test); 
    call.enqueue(new Callback<Test>() { 
        @Override 
        public void onResponse(Call<Test> call, Response<Test> response) { 
            if (response.isSuccessful()) {
                Toast.makeText(ActivityTest.this, "更新成功", Toast.LENGTH_LONG).show();
            } else {
                // 打印错误响应详情
                try {
                    String errorInfo = response.errorBody().string();
                    Toast.makeText(ActivityTest.this, "响应错误: " + errorInfo, Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } 
        @Override 
        public void onFailure(Call<Test> call, Throwable t) { 
            Toast.makeText(ActivityTest.this, "请求失败: " + t.getMessage(), Toast.LENGTH_LONG).show(); 
        } 
    }); 
}

调试小技巧

  • 用Postman或curl直接调用API测试,比如:
    curl -X PUT -H "Content-Type: application/json" -d '{"name":"test_name","age":"test_age"}' http://你的域名/update.php/3
    
  • 查看PHP错误日志,能快速定位服务器端问题
  • 确认数据库用户有UPDATE权限,且test表的字段名(name、age、id)完全正确

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:09:12