今天做项目的时候碰见一个问题:之前一个同事离职之前做了一个网站,有一个上传商品详细图片的功能,当时已经完成,但是由于后期程序的有更改以及更改的程序员的水平也是参差不齐,最后导致程序bug很多,由于当时用的是一个框架,最终也没找到说明文档,后来我就重新写了一个结合ajax上传文件的upload.classs.php虽然界面欠缺美观,但是通俗易懂好维护.
//首先是页面.
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>upload</title>
<script src="source/jquery.js"></script>
<script src="source/jquery.form.js"></script>
</head>
<body>
<form method="post" id="picform" enctype="multipart/form-data">
<input type="file" name="file">
</form>
<div id='pics'></div>
<form action="model.php" id="infofrom" method="post">
<input type="submit" value="submit">
</form>
</body>
<script>
$(":file").change(function(){
if(!$(this).val())
{
alert('请选择图片!');
return false;
}
$("#picform").ajaxSubmit({
type:'post',
url:'upload.php',
success:function(data){
switch(data)
{
case '0':
alert('文件存放目录不存在');
break;
case '1':
alert('系统错误,请检查环境配置');
break;
case '2':
alert('文件类型不允许');
break;
case '3':
alert('文件大小有误');
break;
default:
var obj= $.parseJSON(data);
//生成缩略图
$("#pics").append("<img width='100px' height='100px' src="+obj.relpicpath+" />");
var len= $("#infofrom :hidden").length;
if(len==0)
{
$("#infofrom").append("<input type='hidden' value='"+obj.picname+"' id='picname' name='picname'>");
$("#infofrom").append("<input type='hidden' value='"+obj.picpath+"' id='picpath' name='picpath'>");
$("#infofrom").append("<input type='hidden' value='"+obj.relpicpath+"' id='relpicpath' name='relpicpath'>");
}
else
{
$("#picname").val($("#picname").val()+','+obj.picname);
$("#picpath").val($("#picpath").val()+','+obj.picpath);
$("#relpicpath").val($("#relpicpath").val()+','+obj.relpicpath);
}
break;
}
}
})
})
</script>
</html>
//接收前台ajax的页面
upload.php
<?php
include_once 'Upload.class.php';
$obj=new Upload('uploads',array('.jpg'),3145728,'file');
$arr=$obj->uploadFiles();
if(is_array($arr))
{
echo json_encode($arr);
}
else
{
echo $arr;
}
?>
//简单的文件上传类
upload.class.php
<?php
//文件上传类
class Upload{
private $path; //上传路径
private $allowtype=array(); //资源类型
private $maxsize; //允许上传的文件大小
private $file; //file表单的name
private $error=1; //定义路径不存在的错误
//构造方法
public function __construct($path,$allowtype,$maxsize,$file)
{
$this->path = $path;
//首先检查文件路径是否存在
if(!file_exists($this->path))
{
$this->error=0;
// exit('ERROR:文件路径不存在!');
}
$this->allowtype = $allowtype;
$this->maxsize = $maxsize;
$this->file = $file;
}
//上传一个资源的方法
public function uploadFiles()
{
if($this->error==0)
{
return 0;
}
//首先判断系统是否允许上传,以及有没有出现error
$eor= $_FILES[$this->file]['error'];
if($eor!=0)
{
return 1;//异步传输专用
// exit("ERROR:错误编号:{$eor}!");
}
//判断文件的扩展名
$suf= strrchr($_FILES[$this->file]['name'],'.');
if(!in_array($suf,$this->allowtype))
{
return 2;
// exit('ERROR:文件类型被拒绝!');
}
//判断文件的大小
$size= $_FILES[$this->file]['size'];
if($size>$this->maxsize)
{
return 3;
// exit('ERROR:文件过大!');
}
/*当满足上面所有的条件的时候,进行文件上传
并且返回资源的绝对路径
相对路径
以及文件名*/
$tempname = $_FILES[$this->file]['tmp_name'];
date_default_timezone_set('PRC');
$newname = date('YmdHis').'-'.mt_rand(100,999).$suf;
$rootpath=dirname(__FILE__).'/'.$this->path.'/'.$newname;
if(move_uploaded_file($tempname,$this->path.'/'.$newname))
{
return array('picname'=>$newname,'picpath'=>$rootpath,'relpicpath'=>$this->path.'/'.$newname);
}
}
}
?>
//前台页面提交表单后的入库页面
model.php
<?php
$dbh=new PDO('mysql:host=localhost;dbname=test;','root','');
$dbh->exec('set names utf8');
$_POST['picpath']=addslashes(str_replace('/', '\\', $_POST['picpath']));
$sql="insert into mytab (picname,picpath,relpicpath) values
('$_POST[picname]','$_POST[picpath]','$_POST[relpicpath]')";
$info=$dbh->exec($sql);
?>
//解释:页面非常的简单,当然这是测试用的.
逻辑过程:
1.前台页面index.php:第一个表单专门用来添加图片.通过change事件触发当前表单提交事件.
2.在提交的upload.php页面中,引入upload.class.php.通过数字注释可以得到每个不同的错误返回(在index.php中页面底部的js部分),当上传成功的时候返回图片的绝对地址(更新或者删除数据的时候以便删除没用的图片),图片的名称,以及图片的相对地址(页面展示使用).
3.upload.class.php的返回值通过upload.php进行进一步的判断,如果是数组说明上传成功,如果是单个的数字,说明上传失败.并且将信息返回给前台.
4.index.php接收到upload.php返回的信息,如果为单个数字的话,进行相应的错误提醒.如果是一个json格式的数据,那个通过$.parseJSON将其转变成json对象,并且在下面的js代码中进行调用. 分别为:在页面的第二个form表单中创建input:hidden,将所需要的信息存储起来以便在提交表单的时候进行使用.同时这里也做了一个判断,如果第二个form表单中已经存在乐hidden说明已经不是第一张图片了,所以直接将之后的图片拼接在hidden的value后面.同时,如果成功的话在id为pics的div中会出现100*100缩略图.
5.最后在index.php中点击submit提交所有的图片信息准备入库.在model.php中,直接实例化了pdo,写了一条sql语句进行了测试,结果没有问题.
注意:index.php中要引入:jquery.form.js
在model.php中addslashes()函数很重要,在数据库中单独的一条斜线"\"在我本次的测试中在数据库中这条斜线就不见了.之前也碰掉类似的问题,当时是没有插入进去.所以在这里进行一次转义.
到此整个过程完成.
作为一个php新人,希望在这里和大家共同进步,这个程序可能安全行,性能什么的我都没有考虑到,用起来可能也有一定的局限性.希望大家多多指点.