ThinkPHP教程_PHP框架之ThinkPHP(十三)【文件上传】
一、文件上传
文件上传需要使用到ORG类库包中的Net.UploadFile类,所以得通过import()函数引入该类
1、基本功能
也就是ORG.Net.UploadFile类的基本功能,不过有些功能(对上传的图片文件生成缩略图)得结合ThinkPHP的ORG.Util.Image类实现,不过ORG.Util.Image类不需要手动引入,而是在UploadFile类中upload方法自动引入的!
·基本上传(单文件上传)
·批量上传
批量上传相对于基本上传,只需要修改下表单即可
UploadFile类会自动识别批量上传,所以基本上传和批量上传有关UploadFile类的操作是一样的,主要是上传成功之后返回的文件信息有细微差异。返回的都是一个包含上传文件的信息的二维数组(文件信息在内层数组中),只不过基本上传返回的二维数组只包含一个元素,而批量上传返回的二维数组包含多个元素!进而影响将上传的文件信息保存到数据库中的操作而已,其实也没多差别,反正都是二维数组,直接使用addAll()方法批量插入即可
·支持图片生成缩略图
如果上传的文件是图片,则可以生成缩略图进行保存
·自定义参数上传
·上传检测
比如文件大小、文件后缀、文件类型等等。ps,文件后缀与文件类型不是一回事
·支持覆盖方式
·支持上传类型、附件大小、上传路径定义
·支持子目录保存上传文件
开启子目录保存上传文件后,会自动生成子目录,且子目录的生成方式有hash和日期两种,且如果是日期,还可以定义日期格式
·支持上传文件的hash验证
2、上传表单
特别注意,必须要在表单中添加enctype="multipart/form-data"属性,否则该表单不支持文件上传功能
3、上传动作
为了结构优化,将上传动作分为两个部分,即在FileAction模块中定义两个private方法,分别是up()方法和keepToDb()方法,然后在upload动作中依次调用这两个方法!
·up()方法
主要功能就是上传文件
ps,UploadFile类的一些属性的功能可以参考源码或手册,但是个人建议看源码,因为注释得很明白!
#maxSize:文件上传的最大文件大小,以字节为单位,默认为-1,表示不限大小
#savePath:文件保存路径(必须)
#saveRule:上传文件的保存规则,必须是一个无需任何参数的函数名,例如可以是 time、uniqid、com_create_guid等,但必须能保证生成的文件名是唯一的,默认是uniqid。实际上这里就是指定一个回调函数,来生成一个唯一的字串作为保存文件的文件名,所以完全可以自定义一个回调函数,只要能保证生成的字符串是唯一的即可
#hashType:上传文件的哈希验证方法,默认是md5_file。也可以是sha1_file,同理也是指定一个回调函数!
#autoCheck:是否自动检测附件,默认为自动检测,即值为true
#uploadReplace:存在同名文件是否覆盖,默认为不覆盖,即值为false
#allowExts:允许上传的文件后缀,默认为空数组,不做后缀检查
#allowTypes:允许上传的文件类型,默认为空数组,不做后缀检查
#autoSub:是否使用子目录保存文件,默认不使用,即值为false
以下3项是在开启子目录保存文件是生效
#subType:子目录创建方式,默认为hash,可以设置为hash或date
#dateFormat:date方式创建子目录时,日期格式,默认为Ymd
#hashLevel:hash方式创建子目录时,子目录层数,默认为1层
------
#thumb:如果上传的文件是图片,是否生成缩略图,默认为不生成,即值为false
以下6项是在开缩略图生成时生效
#thumbMaxWidth:缩略图的最大宽度,如果生成多个(根据每一张图生成多个),则用,分隔
#thumbMaxHeight:缩略图的最大高度,如果生成多个(同理),则用,分隔
#thumbPrefix:缩略图文件名前缀,默认为thumb_,如果有多个(同理),则用,分隔,否则其它的没有前缀
#thumbFixfix:缩略图文件名后缀,默认为空
#thumbPath:缩略图的保存路径,默认为空,留空的则为savePath
#thumbFile:缩略图的文件名,默认为为空,即为上传文件名加上前后缀(指定了的话)
#thumbRemoveOrigin:生成缩略图之后是否删除原图,默认为不删除,即值为false
设置好上传的参数后,就可以调用UploadFile类的upload方法进行附件上传,如果失败,返回false,那么可以用getErrorMsg方法获取错误提示信息;如果上传成功,返回true,则可以通过调用getUploadFileInfo方法获取成功上传的附件信息列表。因此getUploadFileInfo方法的返回值是一个二维数组,其中外层元素就是上传的附件信息。每个附件信息又是一个记录了下面信息的数组
#key:附件上传的表单名称
#savepath:上传文件的保存路径
#name:上传文件的原始名称,即在客户端机器中保存的文件名
#savename:上传文件的保存名称,即在服务器端机器中保存的文件名
#size:上传文件的大小
#type:上传文件的MIME类型
#extension:上传文件的后缀类型
#上传文件的哈希验证字符串
那么就可以通过获取到附加信息写入到数据库中,通常只需要savepath,当然也可以将其他信息写入!附件信息有两种保存方式,一是就保存到当前数据表(即与表单中其它信息一同存入一张表中,比如说将用户名、姓名、联系方式、简历附件savepath存入一张表)、二是单独保存到附件表中(即表单中其它信息如用户名、姓名、联系方式存入信息表中,而简历附件savepath存入附件表,再在附件表中设置一个字段与信息表关联即可)
·keepToDb()方法
4、源码
1 <html> 2 <head> 3 <title>文件上传</title> 4 </head> 5 <body> 6 <volist name=\'files\' id=\'file\'> 7 <img src="__PUBLIC__/Uploads/{$file.file_path}"/> 8 </volist> 9 <form action="__URL__/upload" method="post" enctype="multipart/form-data"> 10 用户名:<input type="text" name="username"/><br/> 11 选择文件:<input type="file" name="file[]"/><br/> 12 <input type="file" name="file[]"/><br/> 13 <input type="submit" value="上传"/> 14 </form> 15 </body> 16 </html>
1 <?php 2 class FileAction extends Action{ 3 public function index(){ 4 $File=new Model(\'File\'); 5 6 $files=$File->select(); 7 8 $this->assign("files",$files); 9 10 $this->display(); 11 } 12 13 public function upload(){ 14 if(empty($_FILES)){ 15 $this->error("请选择上传的文件"); 16 }else{ 17 $file=$this->up(); 18 19 if($this->keepToDb($file)){ 20 $this->success(\'上传成功\'); 21 }else{ 22 $this->error(\'写入数据库失败\'); 23 } 24 } 25 } 26 27 // 文件上传 28 private function up(){ 29 import(\'ORG.Net.UploadFile\'); 30 $upload = new UploadFile();// 实例化上传类 31 $upload->maxSize = 3145728 ;// 设置附件上传大小 32 $upload->allowExts = array(\'jpg\', \'gif\', \'png\', \'jpeg\');// 设置附件上传类型 33 $upload->savePath = \'./Public/Uploads/\';// 设置附件上传目录 34 $upload->saveRule=\'uniqid\';//设置保存文件名生成方式 35 $upload->autoSub=true;//开启子目录保存文件 36 $upload->subType=\'date\';//设置子目录名生成方式 37 38 //与缩略图有关 39 $upload->thumb=true;//开启保存缩略图功能 40 $upload->thumbMaxWidth=\'400,200\';//设置缩略图大小 41 $upload->thumbMaxHeight=\'200,100\'; 42 43 $upload->uploadReplace=true; 44 45 $upload->thumbPrefix=\'m_,s_\';//设置缩略图文件名前缀 46 47 $upload->thumbPath=\'./Public/Uploads/Thumb/\';//设置缩略图保存路径 48 49 if(!$upload->upload()) {// 上传错误提示错误信息 50 $this->error($upload->getErrorMsg()); 51 52 }else{// 上传成功 53 return $upload->getUploadFileInfo();//上传成功返回上传文件的信息 54 } 55 } 56 57 private function keepToDb($file){ 58 $File=M(\'File\'); 59 60 /** 61 *将所要插入的数据倒腾到$data[][]中 62 */ 63 for($i=0;$i<count($file);$i++){ 64 65 $data[$i][\'file_path\']=$file[$i][\'savename\']; 66 } 67 return $File->addAll($data); 68 } 69 } 70 71 ?>