Android WebView 文件上传问题:通过PHP上传图片至MySQL数据库
实现Android WebView图片上传到MySQL的PHP方案
整体逻辑说明
你已经完成的文件选择器只完成了前端选图环节,后续需要走「H5表单提交→PHP后端接收处理→数据写入MySQL」的完整流程,以下是分步实现代码:
1. H5前端表单编写(WebView加载的页面)
必须给表单设置multipart/form-data编码类型,否则无法传输文件内容:
<form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="upload_img" accept="image/*"> <button type="submit" name="submit">上传图片</button> </form>
如果你的页面是前后端分离架构,也可以用FormData对象通过AJAX提交,逻辑和表单提交一致
2. MySQL表结构设计
通常有两种存储方案,推荐第一种(存文件路径),性能远高于直接存二进制到数据库:
方案1:图片存服务器磁盘,数据库存路径
CREATE TABLE `upload_images` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `image_path` varchar(255) NOT NULL COMMENT '图片存储相对路径', `file_size` int NOT NULL COMMENT '文件大小 单位字节', `upload_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
方案2:图片二进制直接存数据库(仅适合小图场景)
CREATE TABLE `upload_images` ( `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, `image_blob` longblob NOT NULL COMMENT '图片二进制内容', `file_type` varchar(20) NOT NULL COMMENT '图片MIME类型', `file_size` int NOT NULL COMMENT '文件大小 单位字节', `upload_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3. PHP后端处理代码(upload.php)
方案1:存储路径到数据库的实现
<?php // 配置参数 $allowed_types = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']; $max_size = 5 * 1024 * 1024; // 最大5MB $upload_dir = './uploads/'; // 服务器存储目录,需提前创建并给755权限 // 校验文件是否上传成功 if (!isset($_FILES['upload_img']) || $_FILES['upload_img']['error'] !== UPLOAD_ERR_OK) { die("上传失败:错误码" . $_FILES['upload_img']['error']); } $file_info = $_FILES['upload_img']; // 校验文件大小 if ($file_info['size'] > $max_size) { die("文件过大,最大支持5MB"); } // 校验文件类型 $finfo = new Finfo(FILEINFO_MIME_TYPE); $mime_type = $finfo->file($file_info['tmp_name']); if (!in_array($mime_type, $allowed_types)) { die("仅支持上传jpg/png/gif/webp格式的图片"); } // 生成唯一文件名,避免重名覆盖 $ext = pathinfo($file_info['name'], PATHINFO_EXTENSION); $file_name = uniqid() . '.' . $ext; $save_path = $upload_dir . $file_name; // 移动文件到存储目录 if (!move_uploaded_file($file_info['tmp_name'], $save_path)) { die("文件保存失败,请检查目录权限"); } // 连接数据库写入路径 $db_host = '你的数据库地址'; $db_user = '数据库用户名'; $db_pass = '数据库密码'; $db_name = '数据库名'; $conn = new mysqli($db_host, $db_user, $db_pass, $db_name); if ($conn->connect_error) { die("数据库连接失败:" . $conn->connect_error); } // 预处理语句避免SQL注入 $stmt = $conn->prepare("INSERT INTO upload_images (image_path, file_size) VALUES (?, ?)"); $stmt->bind_param("si", $save_path, $file_info['size']); if ($stmt->execute()) { echo "上传成功,图片ID为:" . $stmt->insert_id; } else { echo "数据库写入失败:" . $stmt->error; // 写入失败要删除已经上传的文件 unlink($save_path); } $stmt->close(); $conn->close(); ?>
方案2:存储二进制到数据库的实现
只需修改文件保存后的逻辑即可,不需要移动文件到磁盘:
// 省略前面的文件校验逻辑,直接读取临时文件内容 $image_content = file_get_contents($file_info['tmp_name']); // 写入数据库 $stmt = $conn->prepare("INSERT INTO upload_images (image_blob, file_type, file_size) VALUES (?, ?, ?)"); $stmt->bind_param("bsi", $image_content, $mime_type, $file_info['size']); $stmt->send_long_data(0, $image_content); // 处理大体积二进制数据 if ($stmt->execute()) { echo "上传成功,图片ID为:" . $stmt->insert_id; } else { echo "数据库写入失败:" . $stmt->error; }
常见问题排查
- 如果WebView提交后无响应,先检查Android端WebView的
onShowFileChooser回调是否正确返回了选中的文件Uri,有没有动态申请存储读取权限 - PHP上传失败先检查php.ini配置的
upload_max_filesize和post_max_size是否大于你上传的图片大小 - 上传目录一定要给读写权限,否则会出现文件移动失败的问题
内容的提问来源于stack exchange,提问作者Joyal George
相关产品推荐
相关产品推荐

