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

如何使用React Native与PHP实现图片上传至后端并存储

问题分析

核心问题是:前端用FormData上传图片时,后端未正确接收到文件($_FILES['image']为空),误进入$_POST['imageURI']分支,导致后端尝试访问手机本地的图片路径(该路径在服务器上不存在),触发文件找不到的错误。

解决方案

前端修复(React Native)

1. 完善Fetch请求配置

ApiService的addFood方法中,无需手动设置Content-Type(React Native会自动为FormData添加正确的multipart/form-data头及边界),可按需添加会话保持配置:

addFood: async (foodData) => {
    try {
        const response = await fetch(`${BASE_URL}/foods/add`, {
            method: 'POST',
            body: foodData,
            credentials: 'include' // 可选,若后端需要会话维持
        });

        const responseData = await response.json();
        if (!response.ok) {
            throw new Error(responseData.message || `HTTP error! Status: ${response.status}`);
        }
        return responseData;
    } catch (error) {
        throw error;
    }
},

2. 优化图片URI处理

Expo ImagePicker返回的URI可直接用于FormData,无需额外修改,确保handleImageChange传递正确路径:

const handleImageChange = async (result) => {
    if (result && result.uri) {
        setProductData({ ...productData, imageURI: result.uri });
        console.log('图片URI:', result.uri);
    } else {
        setProductData({ ...productData, imageURI: null });
    }
};

3. 精准构造FormData

动态获取图片的MIME类型和扩展名,避免硬编码导致类型不匹配:

const handleSubmit = async () => {
    try {
        const formData = new FormData();
        formData.append('title', productData.title);
        formData.append('description', productData.description);
        formData.append('category', productData.category);
        formData.append('price', productData.price);
        
        // 动态获取图片类型和扩展名
        const imageAsset = await ImagePicker.getImageInfoAsync(productData.imageURI);
        formData.append('image', {
            uri: productData.imageURI,
            type: imageAsset.mimeType,
            name: `product-image-${Date.now()}.${imageAsset.extension}`,
        });

        const result = await apiService.addFood(formData);
        alert('Plat ajouté avec succès!');
        resetForm();
    } catch (error) {
        console.error(error);
        alert('Une erreur est survenue lors de l\'ajout du plat.');
    }
};

后端修复(PHP)

1. 移除错误的imageURI分支

服务器无法访问手机本地路径,仅处理$_FILES上传的文件:

public function addFood()
{
    if (isset($_POST['title']) && isset($_POST['description']) && isset($_POST['category']) && isset($_POST['price'])) {
        $title = $_POST['title'];
        $description = $_POST['description'];
        $category = $_POST['category'];
        $price = $_POST['price'];
        $imagePath = null;

        // 仅处理文件上传逻辑
        if (isset($_FILES['image']) && $_FILES['image']['error'] === UPLOAD_ERR_OK) {
            $imageFile = $_FILES['image'];
            // 生成唯一文件名,避免覆盖
            $extension = pathinfo($imageFile['name'], PATHINFO_EXTENSION);
            $uniqueName = uniqid() . "." . $extension;
            $imagePath = 'images/' . $uniqueName;
            
            // 确保images目录存在且可写
            if (!is_dir('images')) {
                mkdir('images', 0755, true);
            }
            
            if (!move_uploaded_file($imageFile['tmp_name'], $imagePath)) {
                http_response_code(500);
                echo json_encode(array("message" => "Impossible de sauvegarder l'image."));
                return;
            }
        } else {
            http_response_code(400); 
            echo json_encode(array("message" => "Image manquante ou erreur lors de l'upload."));
            return;
        }

        if ($this->model->addFood($title, $description, $category, $price, $imagePath)) {
            http_response_code(201);
            echo json_encode(array("message" => "Produit ajouté avec succès."));
        } else {
            http_response_code(500);
            echo json_encode(array("message" => "Impossible d'ajouter le produit."));
        }
    } else {
        http_response_code(400); 
        $missingFields = [];
        if (!isset($_POST['title'])) $missingFields[] = 'title';
        if (!isset($_POST['description'])) $missingFields[] = 'description';
        if (!isset($_POST['category'])) $missingFields[] = 'category';
        if (!isset($_POST['price'])) $missingFields[] = 'price';
        echo json_encode(array("message" => "Données manquantes. Veuillez fournir les champs suivants : " . implode(', ', $missingFields)));
    }
}

2. 检查PHP上传配置

确保PHP允许文件上传并设置合理的大小限制:

file_uploads = On
upload_max_filesize = 10M // 根据业务调整
post_max_size = 10M
关键注意事项
  • 禁止从后端访问前端设备的本地路径,必须通过multipart/form-data机制传递图片内容。
  • 确保后端images目录拥有写入权限(设置为0755或0775)。
  • FormData的图片字段必须包含uri、type、name三个属性,缺一不可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 09:54:57