安卓APP数据库交互PHP脚本问题:多查询无变更却返回成功
嘿,我来帮你梳理下这个问题!你遇到的情况其实是PHP mysqli的常见新手坑,咱们一步步拆解解决:
1. 为什么try-catch没触发?因为mysqli默认不抛异常
mysqli默认是用错误码+警告的方式提示问题,不会自动抛出Exception,所以你的try-catch块根本抓不到数据库操作的错误。得先开启mysqli的异常模式,这样出错时才会抛出异常让你捕获:
$con = mysqli_connect(/* 你的连接信息 */) or die ("Unable to connect"); // 开启mysqli异常模式,让错误能被try-catch捕获 mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
2. 核心问题:你没更新用户余额!
看你的代码,只执行了插入Transacties的操作,但完全漏掉了更新Gebruikers表中付款人和收款人的余额!这就是数据库没任何变更的关键原因之一!
而且,插入交易和更新余额这三个操作(插交易+改付款人余额+改收款人余额)应该放在事务里,保证原子性——要么全部成功,要么全部回滚,避免出现数据不一致的情况(比如交易插了,但余额没更新)。
修改后的事务代码如下:
try { // 开启事务 mysqli_begin_transaction($con); // 1. 插入交易记录 $statement2 = mysqli_prepare($con, "INSERT INTO Transacties (idBetaler, idOntvanger, Bedrag, Datum, Uitgevoerd) VALUES(?, ?, ?, now(), 1)"); mysqli_stmt_bind_param($statement2, "iid", $idBetaler, $idOntvanger, $bedrag); mysqli_stmt_execute($statement2); // 2. 更新付款人余额 $updateBetaler = mysqli_prepare($con, "UPDATE Gebruikers SET Saldo = ? WHERE idGebruiker = ?"); mysqli_stmt_bind_param($updateBetaler, "di", $saldoBetaler, $idBetaler); mysqli_stmt_execute($updateBetaler); // 3. 更新收款人余额 $updateOntvanger = mysqli_prepare($con, "UPDATE Gebruikers SET Saldo = ? WHERE idGebruiker = ?"); mysqli_stmt_bind_param($updateOntvanger, "di", $saldoOntvanger, $idOntvanger); mysqli_stmt_execute($updateOntvanger); // 所有操作成功,提交事务 mysqli_commit($con); $response["success"] = "success"; } catch(mysqli_sql_exception $e) { // 出错就回滚,撤销所有操作 mysqli_rollback($con); // 注意:是getMessage()不是gettext! $response["success"] = $e->getMessage(); }
3. 先确认是否查询到了接收者用户
如果$gebruikersnaamOntvanger对应的用户不存在,那while(mysqli_stmt_fetch($statement))循环不会执行,$idOntvanger和$saldoOntvanger会是未定义状态,后续操作肯定出问题。
应该先判断查询结果是否存在:
mysqli_stmt_store_result($statement); mysqli_stmt_bind_result($statement, $idGebruiker, $Saldo); // 检查是否找到接收者 if(mysqli_stmt_num_rows($statement) === 0) { $response["success"] = "接收者用户名不存在"; echo json_encode($response); exit; // 直接终止脚本,避免后续错误 } // 因为用户名是唯一的,不需要while循环,一次fetch就够了 mysqli_stmt_fetch($statement); $idOntvanger = $idGebruiker; $saldoOntvanger = $Saldo;
4. 检查参数绑定的类型是否正确
在插入交易的绑定中,你用了"iid"——表示前两个参数是int,第三个是int。如果$bedrag是小数(比如12.5欧元),那第三个参数类型应该用d(double),改成"idd",不然小数部分会被截断。
5. 调试小技巧:开启错误显示
开发阶段可以在脚本最顶部加上这两行,方便看到PHP的错误信息(比如未定义变量、语法错误):
error_reporting(E_ALL); ini_set('display_errors', 1);
把这些修改整合后,你的脚本应该就能正常更新数据库,并且能正确捕获和返回错误信息了!
内容的提问来源于stack exchange,提问作者dragonq1

