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

Flutter对接PHP API登录时获取用户数据触发Socket异常排查

问题:Flutter对接PHP API登录出现Socket异常

原本Flutter应用对接PHP API的登录功能运行正常,添加获取客户端ID和姓名并用于页面间传递的逻辑后出现Socket异常,且该异常在添加PHP中的userID返回逻辑前就已出现,添加后问题仍存在。

相关代码

PHP代码

include_once "database.php";
include_once "cores.php";

$phone = $_POST['phone'];

$select = "SELECT * FROM `client` WHERE `phone`='$phone' AND `status`='Active' ";
$run = mysqli_query($connect, $select);


if (mysqli_num_rows($run) > 0) 
{
    $userData = array();

    while ($row = mysqli_fetch_assoc($run))
    {
        $userData = $row;
    }


    echo json_encode(
        array(
            "check" => true, 
            "userID" => $userData[0]
        )
    );

} 
else 
{
    echo json_encode(array("check" => false));
}

Flutter代码

Future<void> LoginClient() async
{

  if (phone.text.isNotEmpty) 
  {
    try 
    {

      var validate = await http.post(
        Uri.parse(ApisConnect.checkPhoneNumberApi),
        body: {
          "phone" : phone.text
        }
      );

      var response1 = jsonDecode(validate.body);

      if (response1["exists"] == true) 
      {
        var login = await http.post(
        Uri.parse(ApisConnect.loginApi),
          body: {
            "phone": phone.text,
          },
        );

        var response2 = jsonDecode(login.body);

        if (response2["check"] == true) 
        {
          Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => DashboardScreen()));

          User userInfo = User.fromJson(response2["userID"]);
          
          Fluttertoast.showToast(msg: 'Logined Successfully,'); 
        }
        else if(response2['check'] == false)
        {
          Fluttertoast.showToast(msg: 'You Are blocked, If you have any error call Techneical Support');
        }

      }
      else
      {
        Fluttertoast.showToast(msg: 'This Number not signed, sign up first.');
      }

    } 
    catch (e) 
    {
      Fluttertoast.showToast(msg: 'Error: $e');
    }       
  }
  else
  {
    Fluttertoast.showToast(msg: 'Fill The field first');
  }
}

排查与修复建议

1. 修正PHP代码错误

  • 关联数组索引错误:mysqli_fetch_assoc返回的是关联数组,$userData[0]不存在,需替换为数据库实际的用户ID字段名(如$userData['id']或$userData['client_id']),否则会触发PHP警告,导致返回内容混入错误信息,破坏JSON格式。
  • 清除输出缓冲区:在echo json_encode前添加ob_clean();,确保响应仅返回纯JSON数据,避免额外输出(如空格、警告)干扰Flutter解析。
  • 防范SQL注入:改用预处理语句,避免直接拼接SQL参数,提升安全性同时避免潜在语法错误。

修正后的PHP代码示例:

include_once "database.php";
include_once "cores.php";

$phone = isset($_POST['phone']) ? $_POST['phone'] : '';

// 预处理语句防SQL注入
$select = "SELECT * FROM `client` WHERE `phone`=? AND `status`='Active' ";
$stmt = mysqli_prepare($connect, $select);
mysqli_stmt_bind_param($stmt, "s", $phone);
mysqli_stmt_execute($stmt);
$run = mysqli_stmt_get_result($stmt);

if (mysqli_num_rows($run) > 0) 
{
    $userData = mysqli_fetch_assoc($run);
    ob_clean();
    echo json_encode(
        array(
            "check" => true, 
            "userID" => $userData['id'], // 替换为实际字段名
            "name" => $userData['name'] // 如需返回姓名,添加对应字段
        )
    );
} 
else 
{
    ob_clean();
    echo json_encode(array("check" => false));
}

2. 调整Flutter代码逻辑

  • 页面跳转时机:先获取用户信息再执行页面跳转,避免Navigator.pushReplacement后上下文失效导致的异常。
  • 异常详情排查:在catch块中打印完整错误信息到控制台,区分是Socket连接异常还是JSON解析异常。
  • 用户信息传递:跳转时直接将用户信息传入目标页面,确保数据传递有效。

修正后的Flutter代码示例:

Future<void> LoginClient() async {
  if (phone.text.isNotEmpty) {
    try {
      var validate = await http.post(
        Uri.parse(ApisConnect.checkPhoneNumberApi),
        body: {"phone": phone.text}
      );

      var response1 = jsonDecode(validate.body);

      if (response1["exists"] == true) {
        var login = await http.post(
          Uri.parse(ApisConnect.loginApi),
          body: {"phone": phone.text},
        );

        var response2 = jsonDecode(login.body);

        if (response2["check"] == true) {
          // 先解析用户信息
          User userInfo = User.fromJson({
            "id": response2["userID"],
            "name": response2["name"]
          });
          // 跳转并传递用户信息
          Navigator.pushReplacement(
            context, 
            MaterialPageRoute(
              builder: (context) => DashboardScreen(userInfo: userInfo)
            )
          );
          Fluttertoast.showToast(msg: '登录成功'); 
        } else if(response2['check'] == false) {
          Fluttertoast.showToast(msg: '您已被封禁,如有问题请联系技术支持');
        }
      } else {
        Fluttertoast.showToast(msg: '该号码未注册,请先注册');
      }
    } catch (e) {
      print('错误详情:$e'); // 控制台打印完整错误
      Fluttertoast.showToast(msg: '错误:${e.toString()}');
    }       
  } else {
    Fluttertoast.showToast(msg: '请先填写手机号');
  }
}

3. 额外排查步骤

  • 用Postman或curl测试API接口,确认返回的JSON格式是否正确,无额外错误输出。
  • 检查Flutter控制台的异常详情,明确是网络连接问题还是数据解析问题。
  • 确认服务器防火墙、请求频率限制未阻止Flutter应用的请求。
  • 检查AndroidManifest.xml(Android)或Info.plist(iOS)的网络权限配置是否完整。

内容的提问来源于stack exchange,提问作者King Yossef Reda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 01:00:17