php多图片上传预览删除实现
程序员文章站
2022-05-30 08:34:20
...
php多图片上传预览删除实现
最近需要用到这个效果,苦苦挣扎了两天,最后终于实现了想要的效果,特地再次复盘,理清一下思路:
第一步、理清思路,流程梳理:
前端通过 input 可以选择【多图或单图】上传,选择图片后,通过ajax提交表单到后台,后台php处理多图片上传,并返回数据【图片的保存路径,图片名称】!
ajax接受返回的数据,然后创建<img>和<input>元素并绑定返回的图片地址和id,插入html文档,前端达到预览图片的效果,还可实现删除和设为封面等操作!
前端实现步骤:
1、理清要达到的静态效果【死去活来:先写死的页面,然后一步一步动态化!】
2、开始编写html页面和css
首先html页面,需要一个多图片上传框,其次需要一个显示图片的列表框!
上传图片框:<input type="file" name='imgFile[]' multiple accept="image/*" οnchange="upload(this)">
知识点:要想图片上传框可以多选图片需要添加【multiple 】,accept设置上传运行的内容格式,
还有一个name=imgFile和name=imgFile[]的区别,
当name=imgFile时候,即使选择了多图也只能上传一张图,
当name=imgFile[]的时候,选择了多图,才能上传多图,但是多图上传后和单图上传的展示形式不同
具体对比见下图:
其次是图片预览的,图片列表形式
html片段
<ul id="piclist" class="clearfix">
<!--预览图片的列表框 id=piclist-->
<li id="20200611214617_11510">
<!--li显示图片的列表,并且带唯一的id-->
<img src="/upload/image/20200611/20200611214617_11510.jpg" class="vt img selected">
<!--预览的图片,设为封面后添加seleted样式-->
<div>
<span class="del"></span>
<!--图片删除按钮 id=del-->
<input type="hidden" name="p_pics[]" value="/upload/image/20200611/20200611214617_11510.jpg">
<!--隐藏字段 p_pics[] 存储保存到数据库中的url-->
</div>
<p><span>设为封面</span></p>
</li>
<li id="20200611214617_66379"><img src="/upload/image/20200611/20200611214617_66379.jpg" class="vt img"><div><span class="del"></span><input type="hidden" name="p_pics[]" value="/upload/image/20200611/20200611214617_66379.jpg"></div><p><span>设为封面</span><input type="hidden" name="url" value="/upload/image/20200611/20200611214617_66379.jpg"></p></li>
</ul>
<div id="mainpic">
<!--隐藏字段 url设置封面图片的url-->
<input type="hidden" name="p_mainpic" value="/upload/image/20200611/20200611214617_11510.jpg">
</div>
css片段
css代码:
#piclist {
padding-top: 5px;
}
#piclist li .del {
position: absolute;
top: 2px;
right: 2px;
display: block;
width: 18px;
height: 18px;
background: url(../img/close2.gif);
cursor: pointer;
}
#piclist li{
width: 48px;
height: 48px;
float: left;
padding: 10px;
position: relative;}
#piclist li .selected {
border: 2px solid green;
}
#piclist li img{ width: 100%}
#piclist li p span {
text-decoration: underline;
color: #069;
cursor: pointer;
}
.vt {
width: 48px;
}
js片段
<script type="text/javascript">
//多图上传选择触发onchange="upload(this)"
function upload(obj){
//alert(123);
var files = obj.files; //获取所有的上传文件数组
var formData = new FormData(); //新建上传表单
if(files.length >10 ) {
alert('图片限制上传10张!');
return;
}
for(var i = 0;i<files.length;i++){
//单图 formData.append("imgFile", files[i]);
formData.append("imgFile[]", files[i]) //往新建表单中添加图片字段
}
//ajax上传新建表单
$.ajax({
url: "/m/index.php?m=upload_car",
type: "POST",
data:formData,
cache:false, //不设置缓存
processData: false, // 不处理数据
contentType: false, // 不设置内容类型
dataType: "json",
success:function(data){
//请求成功时处理php返回的json数据
//console.log(data);
var data=JSON.parse(data);
var i=0;
var div = $('#piclist');
//循环输出数据,并添加到html文档中
for( i; i<data.length;i++)
{
if(data[i].error == 0)
{
//console.log(data[i].url);
var imgid=data[i].id;
imgid=imgid.substring(0,imgid.length-4);
var imgurl=data[i].url;
imgurl=imgurl.substring(2,imgurl.length);
div.append('<li id="'+imgid+'"><img src="' + imgurl + '" class="vt img"><div><span class="del"></span><input type="hidden" name="p_pics[]" value="'+ imgurl +'"></div><p><span>设为封面</span><input type="hidden" name="url" value="'+ imgurl +'"></p></li>');
}
}
},
complete:function(data){
//请求完成的处理
},
error:function(data){
//请求出错处理
}
});
}
//图片删除操作
$("#piclist li div span").live('click', function(){
//ajax触发删除上传的图片
$.get("/m/index.php?m=user&ajax=1&p_id=",{
p_pic : $(this).next().val()
}, function (data, textStatus){
$("li").remove("#"+data); //删除对应的dom元素
});
});
//设为封面操作
$("#piclist li p span").live('click', function(){
$(this).parent().parent().children('.img').addClass("selected");
$(this).parent().parent().siblings().children('.img').removeClass("selected");
$("#mainpic").empty();
$("#mainpic").append('<input type="hidden" name="p_mainpic" value="'+$(this).next().val()+'">');
});
</script>
php代码实现多图上传
//对不同结构的图片上传格式进行统一
function format(){
$files=[];
foreach ($_FILES as $field){
//判断是多图还是单图上传
if(is_array($field['name'])){
foreach ($field['name'] as $id =>$file){
$files[]=[
'name'=>$field['name'][$id],
'type'=>$field['type'][$id],
'error'=>$field['error'][$id],
'tmp_name'=>$field['tmp_name'][$id],
'size'=>$field['size'][$id],
];
}
}else{
$files[]=$field;
}
}
return $files;
}
//PHP图片上传
function up($file){
//文件保存目录路径
$save_path ="/upload/";
//文件保存目录URL
$save_url ='/upload/';
//定义允许上传的文件扩展名
$ext_arr = array(
'image' => array('gif', 'jpg', 'jpeg', 'png', 'bmp')
);
//最大文件大小
$max_size = 1000000;
if (!empty($file['error'])) {
switch($file['error']){
case '1':
$error = '超过php.ini允许的大小。';
break;
case '2':
$error = '超过表单允许的大小。';
break;
case '3':
$error = '图片只有部分被上传。';
break;
case '4':
$error = '请选择图片。';
break;
case '6':
$error = '找不到临时目录。';
break;
case '7':
$error = '写文件到硬盘出错。';
break;
case '8':
$error = 'File upload stopped by extension。';
break;
case '999':
default:
$error = '未知错误。';
}
alert($error);
}
//有上传文件时
if (empty($file) === false) {
//原文件名
$file_name = $file['name'];
//服务器上临时文件名
$tmp_name = $file['tmp_name'];
//文件大小
$file_size = $file['size'];
//检查文件名
if (!$file_name) {
alert("请选择文件。");
}
//检查目录
if (@is_dir($save_path) === false) {
alert("上传目录不存在。");
}
//检查目录写权限
if (@is_writable($save_path) === false) {
alert("上传目录没有写权限。");
}
//检查是否已上传
if (@is_uploaded_file($tmp_name) === false) {
alert("上传失败。");
}
//检查文件大小
if ($file_size > $max_size) {
alert("上传文件大小超过限制。");
}
//检查目录名
$dir_name = empty($_GET['dir']) ? 'image' : trim($_GET['dir']);
if (empty($ext_arr[$dir_name])) {
alert("目录名不正确。");
}
//获得文件扩展名
$temp_arr = explode(".", $file_name);
$file_ext = array_pop($temp_arr);
$file_ext = trim($file_ext);
$file_ext = strtolower($file_ext);
//检查扩展名
if (in_array($file_ext, $ext_arr[$dir_name]) === false) {
alert("上传文件扩展名是不允许的扩展名。\n只允许" . implode(",", $ext_arr[$dir_name]) . "格式。");
}
//创建文件夹
if ($dir_name !== '') {
$save_path .= $dir_name . "/";
$save_url .= $dir_name . "/";
if (!file_exists($save_path)) {
mkdir($save_path);
}
}
$ymd = date("Ymd");
$save_path .= $ymd . "/";
$save_url .= $ymd . "/";
if (!file_exists($save_path)) {
mkdir($save_path);
}
$rand_str = rand(10000, 99999);
//新文件名
$new_file_name = date("YmdHis") . '_' . $rand_str . '.' . $file_ext;
$new_file_name_small = date("YmdHis") . '_' . $rand_str . '_small.' . $file_ext;
//移动文件
$file_path = $save_path . $new_file_name;
if (move_uploaded_file($tmp_name, $file_path) === false) {
alert("上传文件失败。");
}
@chmod($file_path, 0644);
$file_url = $save_path . $new_file_name;
if(isImage($file_url) == false){
unlink($file_url);
alert("不是真实图片,不允许上传!");
}
//返回上传图片存储地址和文件名及是否报错
return array('error' => 0, 'url' => $file_url,'id'=>$new_file_name);
//exit;
}
}
//调用上方的两个函数
//统一单图和多图上传文件格式
$files = format($_POST);
//var_dump($files);
//存放返回前端的url数据
$urls=[];
foreach ($files as $file){
//循环上传,保存上传返回数据
$urls[]= up($file);
}
//var_dump($urls); //二维数组
//return $urls;
//echo json_encode($urls);
echo json_encode($urls); //转换成json字符串数组
php上传类【使用多图和单图】参照:https://www.cnblogs.com/chenguosong/p/11870114.html
<?php
class uploader{
protected $dir;
public function make(){
$this->makedir();
$files = $this->format();
$saveFiles=[];
foreach($files as $file)
{
if($file['error']==0)
{
if(is_uploaded_file($file['tmp_name']))
{
$to =$this->dir.'/'.time().mt_rand(1,9999).'.'.pathinfo($file['name'])['extension'];
if(move_uploaded_file($file['tmp_name'],$to))
{
$saveFiles[]=[
'path'=> $to,
'size'=>$file['size'],
'name'=>$file['name'],
];
}
}
}
}
return $saveFiles;
}
//创建上传目录
private function makedir(){
$path='uploads/'.date('y/m');
$this->dir=$path;
return is_dir($path) or mkdir($path,0755,true);
}
private function format(){
$file=[];
foreach($_FILES as $field){
if(is_array($field['name'])){
foreach($field['name'] as $id=>$file)
{
$files[]=[
'name'=>$field['name'][$id],
'type'=>$field['type'][$id],
'error'=>$field['error'][$id],
'tmp_name'=>$field['tmp_name'][$id],
'size'=>$field['size'][$id],
];
}
}else{
$files[]=$field;
}
}
return $files;
}
}
?>