从零实现React JS+PHP REST API图片上传至MySQL咨询
React 上传图片到PHP接口并存入MySQL完整实现流程
一、前期环境与数据库准备
- 本地环境:直接用XAMPP/WAMP这类集成环境即可,一键装好Apache、PHP、MySQL,省去手动配置的麻烦
- React项目:提前用Vite或者Create React App初始化好前端项目,安装
axios依赖用于发请求 - 数据库初始化:打开MySQL管理工具(比如phpMyAdmin),执行以下SQL建库建表:
CREATE DATABASE IF NOT EXISTS react_img_demo; USE react_img_demo; CREATE TABLE IF NOT EXISTS uploaded_images ( id INT AUTO_INCREMENT PRIMARY KEY, file_name VARCHAR(255) NOT NULL COMMENT '原始文件名', file_type VARCHAR(50) NOT NULL COMMENT '文件MIME类型', image_base64 LONGTEXT NOT NULL COMMENT 'base64格式图片内容', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) DEFAULT CHARSET=utf8mb4;
注意:存base64内容的字段必须用
LONGTEXT类型,普通TEXT类型最大只能存64KB内容,稍微大一点的图片就会被截断。
二、PHP后端接口开发
把所有PHP文件放到Web服务器的根目录对应项目文件夹下,比如XAMPP的htdocs/react-img-upload目录,后续接口地址就是http://localhost/react-img-upload/xxx.php。
1. 数据库连接文件 db.php
<?php // 改成你自己本地的数据库配置 $db_host = 'localhost'; $db_name = 'react_img_demo'; $db_user = 'root'; // 本地集成环境默认账号一般为root $db_pwd = ''; // XAMPP默认MySQL密码为空,根据自己的配置修改 $conn = new mysqli($db_host, $db_user, $db_pwd, $db_name); if ($conn->connect_error) { die("数据库连接失败:" . $conn->connect_error); } $conn->set_charset('utf8mb4'); ?>
2. 图片上传接口 upload.php
<?php // 配置跨域,本地开发用,生产环境请替换成自己的前端域名,不要用* header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: POST, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); header("Content-Type: application/json; charset=utf-8"); // 处理浏览器跨域预检OPTIONS请求 if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; } // 只允许POST请求访问 if ($_SERVER['REQUEST_METHOD'] !== 'POST') { http_response_code(405); echo json_encode(['code' => 405, 'msg' => '请求方法不允许']); exit; } // 引入数据库连接 require_once './db.php'; // 获取前端POST过来的JSON数据 $raw_post = file_get_contents('php://input'); $post_data = json_decode($raw_post, true); // 参数校验 if (empty($post_data['file_name']) || empty($post_data['file_type']) || empty($post_data['image_base64'])) { http_response_code(400); echo json_encode(['code' => 400, 'msg' => '缺少必填参数']); exit; } // 转义参数,避免SQL注入(生产环境更推荐用PDO预处理语句) $file_name = $conn->real_escape_string($post_data['file_name']); $file_type = $conn->real_escape_string($post_data['file_type']); $image_base64 = $conn->real_escape_string($post_data['image_base64']); // 写入数据库 $sql = "INSERT INTO uploaded_images (file_name, file_type, image_base64) VALUES ('{$file_name}', '{$file_type}', '{$image_base64}')"; if ($conn->query($sql) === true) { echo json_encode([ 'code' => 200, 'msg' => '图片上传成功', 'data' => ['img_id' => $conn->insert_id] ]); } else { http_response_code(500); echo json_encode(['code' => 500, 'msg' => '数据库写入失败:' . $conn->error]); } $conn->close(); ?>
三、React前端上传组件实现
在React项目中新建上传组件,核心逻辑是:用户选择图片后,用FileReader把图片转成base64格式,再通过POST请求把数据传给PHP接口。示例代码如下:
import { useState } from 'react'; import axios from 'axios'; export default function ImageUpload() { const [currentFile, setCurrentFile] = useState(null); const [previewSrc, setPreviewSrc] = useState(''); const [tipMsg, setTipMsg] = useState(''); // 处理文件选择 const onFileChange = (e) => { const file = e.target.files[0]; if (!file) return; if (!file.type.startsWith('image/')) { setTipMsg('请选择有效的图片文件'); return; } setCurrentFile(file); setPreviewSrc(URL.createObjectURL(file)); setTipMsg(''); }; // 图片转base64工具方法 const fileToBase64 = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = err => reject(err); }); }; // 处理上传逻辑 const onUploadSubmit = async () => { if (!currentFile) { setTipMsg('请先选择要上传的图片'); return; } try { setTipMsg('正在上传...'); const base64Data = await fileToBase64(currentFile); // 接口地址替换成你自己本地的upload.php访问地址 const res = await axios.post('http://localhost/react-img-upload/upload.php', { file_name: currentFile.name, file_type: currentFile.type, image_base64: base64Data }); setTipMsg(res.data.msg); } catch (err) { setTipMsg('上传失败:' + (err.response?.data?.msg || err.message)); } }; return ( <div style={{ maxWidth: 480, margin: '60px auto' }}> <h2>图片上传演示</h2> <input type="file" accept="image/*" onChange={onFileChange} /> {previewSrc && ( <div style={{ margin: '20px 0' }}> <img src={previewSrc} alt="图片预览" style={{ maxWidth: '100%', maxHeight: 300 }} /> </div> )} <button onClick={onUploadSubmit} style={{ padding: '8px 24px', marginTop: 10 }}> 确认上传 </button> {tipMsg && <p style={{ marginTop: 16 }}>{tipMsg}</p>} </div> ); }
把这个组件引入到App.js里启动项目,就能测试上传流程了。
四、常见问题与优化建议
- 跨域报错:先检查PHP接口的跨域头是否正确配置,确认本地Apache/PHP服务正常启动,接口地址可以直接在浏览器访问到
- 大图片上传失败:修改PHP配置文件
php.ini,把post_max_size、upload_max_filesize两个参数调整到你需要的大小(比如20M),改完重启Web服务生效 - 数据库写入内容不全:确认
image_base64字段类型是LONGTEXT,不要用TEXT、MEDIUMTEXT这类容量更小的类型 - 生产环境优化:不推荐把图片base64直接存在数据库,会导致数据库体积快速膨胀,查询性能下降。更合理的方案是PHP收到图片后,把图片文件存到服务器本地磁盘或者云对象存储,数据库只存文件的访问URL、文件名、大小等元数据;另外必须加文件大小限制、文件后缀/MIME校验,数据库操作用PDO预处理语句避免SQL注入风险。
内容的提问来源于stack exchange,提问作者Hello Friend
相关产品推荐
相关产品推荐

