layui+php实现多文件上传「代码演示」

1. 前言

实现多文件上传这个功能,已经是后台开发中很常见的需求了。当前主流的前端框架都提供了直接的上传控件,如vue-upload-component、iview中的upload等,它们使前端开发人员实现上传功能变得轻松便捷。但当我们需要自行实现上传功能时,不同的后台语言具有不同的处理方式。这篇文章将介绍如何使用layui+php实现多文件上传这一功能。

2. 项目结构

首先,创建项目文件夹,文件夹下分别创建“index.html”、“upload.php”和“layui”文件夹,如下所示:

- 项目文件夹

|__ index.html

|__ upload.php

|__ layui/

其中,“index.html”文件用于前端页面,我们需要使用layui库中的组件来实现上传功能;“upload.php”文件用于接收前端传递的数据和上传的文件,并实现上传到指定目录中的功能;“layui”文件夹用于存放layui库中的静态资源(js、css)。

3. 前端页面

3.1 页面结构

我们使用layui中的upload组件来实现上传功能。首先在“index.html”中添加如下代码:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>layui+php实现多文件上传</title>

<link rel="stylesheet" href="./layui/css/layui.css">

</head>

<body>

<div class="layui-upload">

<button type="button" class="layui-btn layui-btn-normal" id="testList">上传图片</button>

<div class="layui-upload-list">

<table class="layui-table">

<thead>

<tr>

<th>文件名</th>

<th>大小</th>

<th>状态</th>

<th>操作</th>

</tr>

</thead>

<tbody id="demoList">

</tbody>

</table>

</div>

</div>

<script src="./layui/layui.js"></script>

<script>

//JavaScript代码块

</script>

</body>

</html>

整个页面结构中有一个div,使用了layui-upload组件和layui-table组件,其中upload组件用于渲染上传按钮,table组件用于渲染上传后的文件列表。我们需要在JavaScript中实现关于upload组件的操作。在页面结构后,需要通过script标签来引入layui库和自定义JavaScript代码,如上所示。

3.2 JavaScript代码块

接下来,我们在[xss_clean]标签中,实现JavaScript代码块,达到操作upload组件和文件列表的目的。初次接触Layui的开发者需要注意三个比较重要的概念:模块、元素操作、事件监听。首先我们预先定义好上传组件的实例,然后监听“选择图片”和“开始上传”两个事件,使用ajax上传文件,并将选中的文件信息添加到“demoList”文件列表中。代码如下:

layui.use(['upload', 'layer'], function(){

var $ = layui.jquery,

upload = layui.upload,

layer = layui.layer;

//多文件列表示例

var demoListView = $('#demoList'),

uploadListIns = upload.render({

elem: '#testList',

url: 'upload.php',

accept: 'file',

multiple: true,

auto: false,

bindAction: '#testListAction',

choose: function(obj){

//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)

obj.preview(function(index, file, result){

var tr = $(['<tr id="upload-'+ index +'>',

'<td></td>',

'<td></td>',

'<td>等待上传</td>',

'<td>',

'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>',

'</td>',

'</tr>'].join(''));

//单个重传

tr.find('.demo-reload').on('click', function(){

obj.upload(index, file);

});

//删除

tr.find('.demo-delete').on('click', function(){

delete files[index]; //删除对应的文件

tr.remove();

uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选

});

demoListView.append(tr);

$('tr#upload-'+index).find('td').eq(0).text(file.name);

$('tr#upload-'+index).find('td').eq(1).text((file.size/1024).toFixed(1)+'KB');

});

},

done: function(res, index, upload){

if(res.code == 0){ //上传成功返回值

$('tr#upload-'+index).find('td').eq(2).text('上传成功');

$('tr#upload-'+index).find('td').eq(3).html('<a href="' + res.data.src + '" target="_blank">' +

'<img src="' + res.data.src + '" class="layui-upload-img"></a>');

}else{

$('tr#upload-'+index).find('td').eq(2).text('上传失败');

$('tr#upload-'+index).find('td').eq(3).find('.layui-progress-bar').css('width', '0%');

}

},

error: function(index, upload){

$('tr#upload-'+index).find('td').eq(2).text('上传失败');

$('tr#upload-'+index).find('td').eq(3).find('.layui-progress-bar').css('width', '0%');

}

});

});

上传组件操作代码的详细解释已添加在代码注释中。上述代码实现了多文件上传和删除功能,它会在上传完毕后将上传成功的文件的路径返回给前端页面,以实现查看上传的图片功能。同时,需要创建文件夹“uploads”,用于存放上传的图片文件。最终,“index.html”文件结构大致为:

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<title>layui+php实现多文件上传</title>

<link rel="stylesheet" href="./layui/css/layui.css">

</head>

<body>

<div class="layui-upload">

<button type="button" class="layui-btn layui-btn-normal" id="testList">上传图片</button>

<div class="layui-upload-list">

<table class="layui-table">

<thead>

<tr>

<th>文件名</th>

<th>大小</th>

<th>状态</th>

<th>操作</th>

</tr>

</thead>

<tbody id="demoList">

</tbody>

</table>

</div>

</div>

<script src="./layui/layui.js"></script>

<script>

layui.use(['upload', 'layer'], function(){

var $ = layui.jquery,

upload = layui.upload,

layer = layui.layer;

//多文件列表示例

var demoListView = $('#demoList'),

uploadListIns = upload.render({

elem: '#testList',

url: 'upload.php',

accept: 'file',

multiple: true,

auto: false,

bindAction: '#testListAction',

choose: function(obj){

//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)

obj.preview(function(index, file, result){

var tr = $(['<tr id="upload-'+ index +'>',

'<td></td>',

'<td></td>',

'<td>等待上传</td>',

'<td>',

'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>',

'</td>',

'</tr>'].join(''));

//删除

tr.find('.demo-delete').on('click', function(){

delete files[index]; //删除对应的文件

tr.remove();

uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选

});

demoListView.append(tr);

$('tr#upload-'+index).find('td').eq(0).text(file.name);

$('tr#upload-'+index).find('td').eq(1).text((file.size/1024).toFixed(1)+'KB');

});

},

done: function(res, index, upload){

if(res.code == 0){ //上传成功返回值

$('tr#upload-'+index).find('td').eq(2).text('上传成功');

$('tr#upload-'+index).find('td').eq(3).html('<a href="' + res.data.src + '" target="_blank">' +

'<img src="' + res.data.src + '" class="layui-upload-img"></a>');

}else{

$('tr#upload-'+index).find('td').eq(2).text('上传失败');

$('tr#upload-'+index).find('td').eq(3).find('.layui-progress-bar').css('width', '0%');

}

},

error: function(index, upload){

$('tr#upload-'+index).find('td').eq(2).text('上传失败');

$('tr#upload-'+index).find('td').eq(3).find('.layui-progress-bar').css('width', '0%');

}

});

});

</script>

</body>

</html>

4. 后台部分(upload.php)

4.1 PHP代码块

接下来我们来处理服务器端的代码。在“upload.php”文件中,使用PHP语言处理上传文件的逻辑,并将上传的文件保存到指定目录中。代码如下所示:

<?php

header("Content-Type:text/html;charset=utf-8");

$file = $_FILES['file'];

//文件存储路径

$save_path = dirname(__FILE__) . '/uploads/';

if(!file_exists($save_path)){

mkdir($save_path, 0777, true);

}

$save_name = uniqid() .'.png';

if(move_uploaded_file($file['tmp_name'], $save_path . $save_name)){

$res_arr = array('code' => 0, 'msg' => '', 'data' => array(

'src' => $save_path . $save_name

));

echo json_encode($res_arr);

}

else{

echo '文件上传失败,请重试。';

}

?>

在PHP代码块中,首先将接收到的文件与要上传的路径存储下来,判断要上传的文件存储路径是否存在,如果不存在则创建一个权限为0777的文件夹。然后,通过图片上传时生成的临时文件名和路径,将文件移动到要上传的文件目录下。最后,将上传成功的文件的路径返回给前端页面。需要注意的是,在上传实例化中定义的是url: 'upload.php',这里的url也需要保存一致。

4.2 前置条件

上述php代码中,使用了dirname(__FILE__),该命令在Windows系统中会报错。需要修改php.ini文件中的doc_root为自己的工作目录,或将dirname(__FILE__)修改为__DIR__。

5. 总结

本文主要介绍了如何使用layui+php实现多文件上传功能,上传按钮使用了layui中的upload组件,上传后的文件列表使用了layui中的table组件。在这个过程中,需要注意Layui中的JavaScript操作方式,以及PHP中的文件上传原理,也需要注意php代码的一些前置条件。希望通过本文的介绍,能够帮助更多的读者轻松实现多文件的上传功能。