微信小程序学习实录9:掌握wx.chooseMedia实现多图片文件上传功能(选择图片、预览图片、上传图片)

要实现多图片上传到服务器,需要在小程序前端和PHP后端分别进行相应的设置。

基本流程

微信小程序提供了丰富的API来支持多图片上传功能。在微信小程序中实现多图片的选择、预览以及上传到服务器的功能:

1. 选择图片

使用 wx.chooseImage API 可以让用户从相册或相机选择一张或多张图片。这个API可以设置用户可以选择的图片数量上限(默认9张)。

javascript 复制代码
Page({
  data: {
    images: [] // 用于存储用户选择的图片临时路径
  },

  // 选择图片
  chooseImage: function () {
    const that = this;
    wx.chooseImage({
      count: 9, // 用户最多可以选择的图片张数,默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        // tempFilePaths为一个数组,包含了所选图片的本地临时文件路径
        const tempFilePaths = res.tempFilePaths;
        that.setData({
          images: tempFilePaths
        });
      }
    });
  }
});

2. 预览图片

当用户选择了图片后,你可以提供一个界面来预览这些图片。这可以通过 wx.previewImage API 来实现,它允许用户在一个全屏界面中查看图片。

javascript 复制代码
// 在页面WXML中定义一个展示图片的区域
<view class="image-list">
  <image src="{{item}}" mode="aspectFit" bindtap="previewImage" data-current="{{index}}" 
         wx:for="{{images}}" wx:key="*this" style="width: 100px; height: 100px; margin: 5px;"></image>
</view>

// 在页面JS中处理预览事件
Page({
  // ... 其他代码 ...
  previewImage: function (e) {
    const current = e.currentTarget.dataset.current; // 获取当前点击图片的索引
    wx.previewImage({
      current: this.data.images[current], // 当前显示图片的http链接
      urls: this.data.images // 需要预览的图片http链接列表
    });
  }
  // ... 其他代码 ...
});

3. 上传图片

使用 wx.uploadFile API 可以将选择的图片逐个上传到服务器。你可以在循环中调用该API来上传每一张图片。

javascript 复制代码
// 上传图片
uploadImages: function () {
  const that = this;
  const uploadPromises = this.data.images.map(function (path, index) {
    return new Promise((resolve, reject) => {
      wx.uploadFile({
        url: 'https://yourserver.com/upload', // 你的服务器地址
        filePath: path,
        name: 'file',
        formData: {
          'user': 'test' // 其他额外参数
        },
        success: function (res) {
          console.log('上传成功:', res);
          resolve(res);
        },
        fail: function (err) {
          console.error('上传失败:', err);
          reject(err);
        }
      });
    });
  });

  // 所有图片上传完毕后的操作
  Promise.all(uploadPromises).then(responses => {
    console.log('所有图片已上传:', responses);
    // 更新UI或其他逻辑
  }).catch(error => {
    console.error('部分或全部图片上传失败:', error);
    // 错误处理
  });
}

PHP 后端

在PHP后端,编写脚本来接收并保存这些图片。

php 复制代码
<?php
header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $target_dir = "uploads/"; // 设置目标文件夹
    if (!is_dir($target_dir)) {
        mkdir($target_dir, 0777, true); // 如果目录不存在则创建
    }

    if (isset($_FILES['files'])) {
        $file = $_FILES['files'];
        $filename = basename($file['name']);
        $target_file = $target_dir . uniqid() . '_' . $filename; // 使用uniqid生成唯一文件名

        if (move_uploaded_file($file['tmp_name'], $target_file)) {
            echo json_encode(['status' => 'success', 'message' => '文件上传成功', 'file_path' => $target_file]);
        } else {
            http_response_code(500);
            echo json_encode(['status' => 'error', 'message' => '文件移动失败']);
        }
    } else {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => '缺少文件']);
    }
} else {
    http_response_code(405); // Method Not Allowed
    echo json_encode(['status' => 'error', 'message' => '请求方法不支持']);
}
?>

在这个PHP脚本中,我们检查是否有文件被上传,并且将其移动到目标文件夹。为了避免文件名冲突,我们使用了 uniqid() 函数来生成唯一的文件名前缀。

注意事项

  • 确保服务器上的 uploads 目录存在并且有写权限。
  • 在生产环境中,可能需要增加更多的安全措施,比如验证文件类型、大小限制等。
  • 考虑到用户体验,你可以在上传过程中显示进度条或提示信息。
  • 如果需要一次性处理多个文件上传,而不是逐个处理,那么可能需要修改前端代码,将所有文件一起发送到服务器,并在服务器端循环处理每个文件。

一次性处理多个文件上传

javascript 复制代码
Page({
  data: {
    images: [] // 用于存储用户选择的图片路径
  },

  // 选择图片
  chooseImage: function () {
    var that = this;
    wx.chooseImage({
      count: 9, // 用户最多可以选择的图片张数,默认9
      sizeType: ['original', 'compressed'], // 可以指定是原图还是压缩图,默认二者都有
      sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
      success: function (res) {
        const tempFilePaths = res.tempFilePaths;
        that.setData({
          images: tempFilePaths
        });
        that.uploadImages(tempFilePaths);
      }
    });
  },

  // 上传图片
  uploadImages: function (tempFilePaths) {
    const formData = new FormData();
    tempFilePaths.forEach((filePath, index) => {
      formData.append('files[]', { uri: filePath, name: 'image' + (index + 1) + '.jpg', type: 'image/jpeg' });
    });

    wx.request({
      url: utils.host_domain + 'api/upload.php', // 你的PHP接口地址
      method: 'POST',
      header: {
        'content-type': 'multipart/form-data'
      },
      formData: formData,
      success: function (res) {
        console.log('图片上传成功: ', res.data);
      },
      fail: function () {
        console.error('图片上传失败');
      }
    });
  }
});
php 复制代码
<?php
// api/upload.php

header('Content-Type: application/json');

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
    $target_dir = "uploads/"; // 设置目标文件夹
    if (!is_dir($target_dir)) {
        mkdir($target_dir, 0777, true); // 如果目录不存在则创建
    }

    $uploadedFiles = [];
    $errors = [];

    if (isset($_FILES['files'])) {
        $files = $_FILES['files'];
        foreach ($files['name'] as $key => $value) {
            if ($files['error'][$key] === UPLOAD_ERR_OK) {
                $filename = basename($files['name'][$key]);
                $target_file = $target_dir . uniqid() . '_' . $filename; // 使用uniqid生成唯一文件名

                if (move_uploaded_file($files['tmp_name'][$key], $target_file)) {
                    $uploadedFiles[] = $target_file;
                } else {
                    $errors[] = "文件移动失败: " . $filename;
                }
            } else {
                $errors[] = "文件上传错误: " . $files['error'][$key];
            }
        }
    } else {
        http_response_code(400);
        echo json_encode(['status' => 'error', 'message' => '缺少文件']);
        exit;
    }

    if (empty($errors)) {
        echo json_encode(['status' => 'success', 'message' => '所有文件上传成功', 'file_paths' => $uploadedFiles]);
    } else {
        http_response_code(500);
        echo json_encode(['status' => 'error', 'message' => '部分或全部文件上传失败', 'errors' => $errors, 'file_paths' => $uploadedFiles]);
    }
} else {
    http_response_code(405); // Method Not Allowed
    echo json_encode(['status' => 'error', 'message' => '请求方法不支持']);
}
?>

@漏刻有时

相关推荐
xiaoyaolangwj21 分钟前
高翔【自动驾驶与机器人中的SLAM技术】学习笔记(十三)图优化SLAM的本质
学习·机器人·自动驾驶
静止了所有花开1 小时前
SpringMVC学习笔记(二)
笔记·学习
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
计算机-秋大田2 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
L_cl3 小时前
Python学习从0到1 day26 第三阶段 Spark ④ 数据输出
学习
Mephisto.java4 小时前
【大数据学习 | HBASE】hbase的读数据流程与hbase读取数据
大数据·学习·hbase
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
尚学教辅学习资料6 小时前
基于微信小程序的电商平台+LW示例参考
java·微信小程序·小程序·毕业设计·springboot·电商平台
尘浮生6 小时前
Java项目实战II基于微信小程序的移动学习平台的设计与实现(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·学习·微信小程序·小程序