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

Http.post从PHP取数据存入SharedPreferences后取值为null问题排查

问题排查与解决方案

首先,我们来一步步拆解你遇到的问题:数据库插入成功说明PHP端的核心逻辑没问题,但Dart端存SharedPreferences后跳转取到null,大概率是异步流程顺序问题或者PHP端返回数据的潜在漏洞,下面分点分析并给出修复方案:

一、先修复PHP端的逻辑漏洞

你的PHP代码里有个关键判断错误:isset($query)无法准确判断查询是否获取到有效数据。因为mysqli_query即使查询不到任何结果,也会返回一个空的结果集对象(不会是false),只有SQL语法错误或连接失败时才会返回false。这会导致当bookingID不存在时,$order = mysqli_fetch_array($query)得到null,此时$order['orderID']会触发PHP警告,甚至可能让返回的response['id']为null,直接导致Dart端拿到无效值。

修复后的PHP代码

include "conn.php";
$response = array();
$name = $_POST['name'];
$age = $_POST['age'];
$bookingID = $_POST['id'];

// 先判断查询是否执行成功,且是否有结果
$query = mysqli_query($connect, "SELECT orderID FROM tb_order WHERE bookingID = '$bookingID' ");
if ($query && mysqli_num_rows($query) > 0) {
    $order = mysqli_fetch_array($query);
    $queryResult = $connect->query("INSERT INTO tb_nameage (name, age, orderID) VALUES ('$name', '$age', '" . $order['orderID'] . "') ");
    $response['id'] = $order['orderID'];
    echo json_encode($response);
} else {
    $response['message'] = "Failed to find matching orderID or query error";
    echo json_encode($response);
}

额外提醒:你的代码存在SQL注入风险,建议使用预处理语句替代直接拼接SQL,比如:

$stmt = $connect->prepare("SELECT orderID FROM tb_order WHERE bookingID = ?");
$stmt->bind_param("s", $bookingID);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows > 0) {
    $order = $result->fetch_assoc();
    // 插入操作同样使用预处理
    $stmtInsert = $connect->prepare("INSERT INTO tb_nameage (name, age, orderID) VALUES (?, ?, ?)");
    $stmtInsert->bind_param("sis", $name, $age, $order['orderID']);
    $stmtInsert->execute();
    $response['id'] = $order['orderID'];
    echo json_encode($response);
}

二、修复Dart端的异步流程问题

你的Dart代码有两个核心问题:

  1. setState误用:orderID是数据变量,不需要用setState赋值(setState是用来触发UI重绘的),直接赋值即可,避免不必要的状态更新混淆。
  2. 跳转时机未等待异步操作完成:点击按钮后直接跳转,可能发生在SharedPreferences存值完成之前,导致第二个页面读取到旧的null值。

修复后的Dart代码

// 确保所有异步操作完成后再跳转
delayedSend() async{
    await inputData(); // 等待接口请求并拿到orderID
    await getID();     // 等待SharedPreferences存值完成
    // 在这里执行页面跳转
    Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
}

inputData() async{
    var url = "http://ip/apts/addNameAge.php";
    var respon = await http.post(url, body: { "name": name, "age": age, "id" : bookingID });
    var datauser = json.decode(respon.body);
    // 直接赋值,无需setState
    orderID = datauser['id'];
    // 调试用:打印接口返回数据,确认是否拿到有效orderID
    print("PHP返回的orderID: $orderID");
}

getID() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    // 直接存值,无需setState,加默认值避免null报错
    await preferences.setString('orderID', orderID ?? "");
}

三、额外调试建议

  1. 在Dart的inputData中打印respon.body,确认PHP返回的JSON格式是否正确,是否包含有效的id字段。
  2. 在第二个页面读取SharedPreferences时添加调试打印:
// 第二个页面的初始化逻辑
getSavedOrderID() async{
    SharedPreferences preferences = await SharedPreferences.getInstance();
    String? savedID = preferences.getString('orderID');
    print("从SharedPreferences读取的orderID: $savedID");
}

通过这些调试信息,可以快速定位问题出在接口返回、本地存值还是跳转时机上。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 15:27:50