如何通过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
相关产品推荐
相关产品推荐

