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

如何通过POST将Flutter的DateTime数据传入PHP并写入MySQL数据库

问题根因

你遇到的Error: FormatException: SyntaxError: Unexpected token b in JSON at position 0和日期传值本身没有直接关系:这个报错是Flutter端按JSON解析接口响应时,拿到的内容不是合法JSON,首字符是b——基本可以确定是PHP端抛出了带<b>标签的错误/警告(比如Notice、Warning级别的报错默认会输出<b>Notice</b>: xxx格式的HTML内容),解析时碰到标签开头的b就直接抛错了。
你当前Flutter端用DateFormat生成的yyyy-MM-dd HH:mm:ss格式字符串本身是合法的日期传值,问题主要出在请求头缺失、PHP端错误输出干扰响应格式、日期值和数据库字段不匹配这几个环节。

分步修复方案

1. Flutter端提交逻辑修正

你现有的日期格式化逻辑可以保留,补充请求头声明、增加响应调试打印即可,修正后代码:

import 'package:intl/intl.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

// 日期格式化逻辑无需修改
DateFormat dateFormat = DateFormat("yyyy-MM-dd HH:mm:ss");
String date = dateFormat.format(DateTime.now());

var url = Uri.parse('http://192.168.1.8/konkolata-dashboard/driver.php');
var response = await http.post(
  url,
  // 明确指定表单提交格式,避免特殊字符转义异常
  headers: {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  body: {
    'name' : fullName.text.trim(),
    'assigned' : 'false',
    'assignedTo': 'no',
    'created': date,
    'available': 'true'
  },
);

// 调试阶段先打印原始响应,快速定位PHP端是否有多余输出
print("响应状态码: ${response.statusCode}");
print("原始响应内容: ${response.body}");

// 确认响应为合法JSON后再执行解析
// Map<String, dynamic> res = jsonDecode(response.body);

2. PHP端接收处理逻辑修正

注意:PHP端一定要关闭前端可见的错误输出,否则任何警告、报错的HTML片段都会破坏JSON结构,这是绝大多数这类JSON解析报错的核心诱因
修正后代码:

<?php
// 声明响应格式为JSON
header('Content-Type: application/json');
// 关闭前端错误输出,错误记录到服务器日志即可,避免破坏响应格式
ini_set('display_errors', 0);
error_reporting(E_ALL);

// 参数校验,避免直接访问不存在的$_POST下标抛出警告
if (!isset($_POST['created']) || empty(trim($_POST['created']))) {
    echo json_encode([
        'code' => 400,
        'msg' => 'created参数缺失'
    ]);
    exit;
}

// 日期格式处理,根据MySQL字段类型二选一:
// 👉 如果MySQL存日期的字段是DATETIME类型(需要保留时分秒),用下面这行
$created = date('Y-m-d H:i:s', strtotime($_POST['created']));
// 👉 如果MySQL存日期的字段是DATE类型(只需要年月日),用你原来的逻辑即可
// $created = date('Y-m-d', strtotime($_POST['created']));

// 校验日期解析结果,避免非法格式写入失败
if (!$created) {
    echo json_encode([
        'code' => 400,
        'msg' => '日期格式非法'
    ]);
    exit;
}

// MySQL写入逻辑,必须用预处理语句防SQL注入
// 以下为PDO示例,mysqli写法逻辑一致
$pdo = new PDO('mysql:host=localhost;dbname=你的数据库名;charset=utf8mb4', '数据库用户名', '数据库密码');
$stmt = $pdo->prepare("INSERT INTO driver (name, assigned, assignedTo, created, available) VALUES (?, ?, ?, ?, ?)");
// 布尔值建议转为tinyint类型的0/1存储,不要直接存字符串true/false
$writeRes = $stmt->execute([
    trim($_POST['name']),
    $_POST['assigned'] === 'true' ? 1 : 0,
    trim($_POST['assignedTo']),
    $created,
    $_POST['available'] === 'true' ? 1 : 0
]);

if ($writeRes) {
    echo json_encode([
        'code' => 200,
        'msg' => '数据写入成功'
    ]);
} else {
    echo json_encode([
        'code' => 500,
        'msg' => '数据写入失败'
    ]);
}
?>

3. MySQL端配置注意点

  • 存储日期的字段类型根据需求选择DATE或DATETIME,不要用VARCHAR等字符串类型存储,避免后续日期查询、排序出现异常
  • 字段如果设置为NOT NULL,要么给定默认值,要么插入时必须传值,否则会触发SQL错误
  • 数据库连接必须设置utf8mb4编码,避免特殊字符写入乱码
额外排查项
  • 调试阶段可以先用Postman等工具直接请求PHP接口,确认返回内容是纯JSON,没有多余的HTML、空格、echo调试内容
  • Android设备真机调试需要在AndroidManifest.xml中添加网络权限、允许明文HTTP请求:
<uses-permission android:name="android.permission.INTERNET"/>
<application
  ...
  android:usesCleartextTraffic="true"
  ...>
  • 确认调试设备和运行PHP服务的设备在同一局域网,能正常访问192.168.1.8对应的服务地址

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 08:24:16