Flutter结合PHP实现IoT传感器数据自动上报MySQL数据库方案咨询
PHP对接Flutter实现IoT传感器数据落库MySQL实现方案
整个链路逻辑很直接:Flutter端拿到传感器采集的原始数据后,通过HTTP请求提交到PHP写的接口层,PHP完成鉴权、参数校验后通过预处理语句写入MySQL即可,不需要额外引入复杂组件。
1. 提前建好MySQL存储表
先根据你的传感器数据维度建表,通用结构可以直接参考下面的SQL,根据自己的业务加字段就行:
CREATE TABLE `sensor_data` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `device_id` varchar(64) NOT NULL COMMENT 'IoT设备唯一标识', `sensor_type` varchar(32) NOT NULL COMMENT '传感器类型,如温湿度、气压、PM2.5', `sensor_value` decimal(10,2) NOT NULL COMMENT '传感器采集数值', `collect_time` int unsigned NOT NULL COMMENT '设备端采集时间戳(秒级)', `receive_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '服务端接收数据时间', PRIMARY KEY (`id`), KEY `idx_device_collect` (`device_id`,`collect_time`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='传感器采集数据表';
2. 编写PHP数据接收接口
接口只做4件事:校验请求合法性、校验参数、连接数据库写入、返回结果。别写多余逻辑,注意防注入、加鉴权,参考代码如下:
<?php // 仅允许POST请求访问 if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); exit(json_encode(['code' => 405, 'msg' => '仅支持POST请求'])); } // 基础配置,部署时替换成自己的实际参数 $config = [ 'db_host' => '127.0.0.1', 'db_name' => 'iot_db', 'db_user' => '你的数据库账号', 'db_pwd' => '你的数据库密码', 'access_token' => '自定义接口鉴权密钥,长度至少16位,不要用弱口令' ]; // 鉴权校验:Flutter请求时把token放到请求头里,避免明文拼在URL被日志泄露 $request_token = isset($_SERVER['HTTP_X_ACCESS_TOKEN']) ? trim($_SERVER['HTTP_X_ACCESS_TOKEN']) : ''; if ($request_token !== $config['access_token']) { http_response_code(403); exit(json_encode(['code' => 403, 'msg' => '无访问权限'])); } // 读取Flutter提交的JSON格式请求体 $raw_content = file_get_contents('php://input'); $request_data = json_decode($raw_content, true); if (!$request_data) { http_response_code(400); exit(json_encode(['code' => 400, 'msg' => '请求格式错误,请提交JSON数据'])); } // 必传参数校验 $required_params = ['device_id', 'sensor_type', 'sensor_value', 'collect_time']; foreach ($required_params as $param) { if (!isset($request_data[$param])) { http_response_code(400); exit(json_encode(['code' => 400, 'msg' => "缺少必传参数:{$param}"])); } } // 参数格式过滤,避免非法值入库 $device_id = trim($request_data['device_id']); $sensor_type = trim($request_data['sensor_type']); $sensor_value = floatval($request_data['sensor_value']); $collect_time = intval($request_data['collect_time']); if (empty($device_id) || empty($sensor_type) || $collect_time <= 0) { http_response_code(400); exit(json_encode(['code' => 400, 'msg' => '参数值非法'])); } // PDO连接数据库,用预处理语句写入,彻底避免SQL注入 try { $pdo = new PDO( "mysql:host={$config['db_host']};dbname={$config['db_name']};charset=utf8mb4", $config['db_user'], $config['db_pwd'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); $statement = $pdo->prepare("INSERT INTO sensor_data (device_id, sensor_type, sensor_value, collect_time) VALUES (?, ?, ?, ?)"); $statement->execute([$device_id, $sensor_type, $sensor_value, $collect_time]); exit(json_encode(['code' => 0, 'msg' => '写入成功', 'record_id' => $pdo->lastInsertId()])); } catch (PDOException $e) { http_response_code(500); exit(json_encode(['code' => 500, 'msg' => '服务端存储异常'])); } ?>
3. Flutter端对接注意事项
- 发请求时统一用
application/json格式传参,鉴权token放到自定义请求头X-Access-Token里,不要拼在URL参数中 - 不要每采集到一条数据就发一次请求,建议攒到1020条或者按510秒的固定间隔批量提交,降低请求开销、省流量
- 加本地离线缓存:手机无网络时先把数据存在本地SQLite,等网络恢复后自动补传,避免数据丢失
- 生产环境必须给接口配HTTPS,避免传输过程中数据、鉴权token被窃听
4. 踩坑提醒
- 绝对不要把前端传过来的参数直接拼接进SQL语句,必须用PDO预处理,否则会存在SQL注入风险,数据库很容易被拖库
- 接口必须加鉴权,不要裸奔在公网,否则被爬虫扫到会被灌入大量垃圾数据
- 数据库查询字段提前加好索引,等数据量到百万级再加会锁表影响业务
- PHP生产环境必须关闭错误回显,避免数据库账号、路径这类敏感信息直接暴露给前端
- 时间字段统一存UTC秒级时间戳,不要存各地本地时间,后续做多端时区适配会少很多麻烦
内容的提问来源于stack exchange,提问作者Ghabrimouheb
相关产品推荐
相关产品推荐

