要实现多图片上传到服务器,需要在小程序前端和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' => '请求方法不支持']);
}
?>
@漏刻有时