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
相关产品推荐
相关产品推荐

