Maison > Article > développement back-end > PHP实现文件上传下载——心在忙而已,_PHP教程
这一周都没有写什么东西,是啊,一周时间都没有学习太多新的东西,除了开车。
妈蛋啊,天天中午去学车然后两周没有午觉的日子还是很崩溃的,加上之后工作压力带来的心忙,宝宝不开心啊。
不过,也是自己不是那么能吃苦吧。那天看到的那句话怎么说的来着,我痛恨自己,在简单和困难之前,选择了前者;在什么什么面前,balabala,不是很鸡汤,但有点触动,愿少点矫情和娇气。
PHP实现文件上传与下载——来自mooc网
一、上传原理与配置
1.1 原理
将客户端文件上传到服务器端,再将服务器端的文件(临时文件)移动到指定目录即可。
1.2 客户端配置
所需:表单页面(选择上传文件);
具体而言:发送方式为POST,添加enctype="multipart/form-data"属性,两者缺一不可(但是,优缺点并存,这里也限定了上传的方式和上传的文件之后的调用等方面,后面会说到)
<span><!</span><span>DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"</span><span>></span> <span><</span><span>html</span><span>></span> <span><</span><span>head</span><span>></span> <span><</span><span>meta </span><span>http-equiv</span><span>="Content-Type"</span><span> content</span><span>="text/html; charset=UTF-8"</span><span>></span> <span><</span><span>title</span><span>></span>Insert title here<span></</span><span>title</span><span>></span> <span></</span><span>head</span><span>></span> <span><</span><span>body</span><span>></span> <span><</span><span>form </span><span>action</span><span>="doAction.php"</span><span> method</span><span>="post"</span><span> enctype</span><span>="multipart/form-data"</span><span>></span><span> 请选择您要上传的文件: </span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile"</span> <span>/><</span><span>br</span><span>/></span> <span><</span><span>input </span><span>type</span><span>="submit"</span><span> value</span><span>="上传"</span><span>/></span> <span></</span><span>form</span><span>></span> <span><?</span><span>php </span><span>?></span> <span></</span><span>body</span><span>></span> <span></</span><span>html</span><span>></span>
先是表单页面(请自动忽略前端问题。。。),关键就是form的属性;另外就是input 中用到了type="file"这一点(体现到php的强大的拓展等等)。
然后是doAction
<?<span>php </span><span>//</span><span>$_FILES:文件上传变量 //print_r($_FILES);</span> <span>$filename</span>=<span>$_FILES</span>['myFile']['name'<span>]; </span><span>$type</span>=<span>$_FILES</span>['myFile']['type'<span>]; </span><span>$tmp_name</span>=<span>$_FILES</span>['myFile']['tmp_name'<span>]; </span><span>$size</span>=<span>$_FILES</span>['myFile']['size'<span>]; </span><span>$error</span>=<span>$_FILES</span>['myFile']['error'<span>]; </span><span>//</span><span>将服务器上的临时文件移动到指定位置 //方法一move_upload_file($tmp_name,$destination) //move_uploaded_file($tmp_name, "uploads/".$filename);//文件夹应提前建立好,不然报错 //方法二copy($src,$des) //以上两个函数都是成功返回真,否则返回false //copy($tmp_name, "copies/".$filename); //注意,不能两个方法都对临时文件进行操作,临时文件似乎操作完就没了,我们试试反过来</span> <span>copy</span>(<span>$tmp_name</span>, "copies/".<span>$filename</span><span>); </span><span>move_uploaded_file</span>(<span>$tmp_name</span>, "uploads/".<span>$filename</span><span>); </span><span>//</span><span>能够实现,说明move那个函数基本上相当于剪切;copy就是copy,临时文件还在 //另外,错误信息也是不一样的,遇到错误可以查看或者直接报告给用户</span> <span>if</span> (<span>$error</span>==0<span>) { </span><span>echo</span> "上传成功!"<span>; }</span><span>else</span><span>{ </span><span>switch</span> (<span>$error</span><span>){ </span><span>case</span> 1: <span>echo</span> "超过了上传文件的最大值,请上传2M以下文件"<span>; </span><span>break</span><span>; </span><span>case</span> 2: <span>echo</span> "上传文件过多,请一次上传20个及以下文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 3: <span>echo</span> "文件并未完全上传,请再次尝试!"<span>; </span><span>break</span><span>; </span><span>case</span> 4: <span>echo</span> "未选择上传文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 5: <span>echo</span> "上传文件为0"<span>; </span><span>break</span><span>; } }</span>
先把print_r($_FILES)这个信息看一下
<span>Array ( [myFile] => Array ( [name] => 梁博_简历.doc [type] => application/msword [tmp_name] => D:\wamp\tmp\php1D78.tmp [error] => 0 [size] => 75776 ) )</span>
所以得到的是个二维数组,该怎么用,都是基本的东西(其实我喜欢降维再用);
基本是一眼就懂的东西,不罗嗦,关键有两个:tmp_name临时文件名;error报错信息(代号,后面可以利用);
然后这里看一下doAction后面一部分,利用报错信息来反馈给用户,需要说明的是为什么报错,和报错信息是什么都;
1.3 关于报错
--报错原因
基本上都是超过或者不符合服务器关于上传文件的配置,那么服务器端配置有哪些呢?
先考虑上传我们用了什么?POST,upload
所以在php.ini中找这么几项:
file_upload:On
upload_tmp_dir=——临时文件保存目录;
upload_max_filesize=2M
max_file_uploads=20——允许一次上传的最大文件数量(注意和上面那个的区别,有没有size,别乱想)
post_max_size=8M——post方式发送数据的最大值
其他相关配置
max_exectuion_time=-1——最大执行时间,避免程序不好占用服务器资源;
max_input_time=60
max_input_nesting_level=64——输入嵌套深度;
memory_limit=128M——最大单线程的独立内存使用量
总之都是有关资源的配置。
--错误号
以下(偷懒)引自http://blog.sina.com.cn/s/blog_3cdfaea201008utf.html
UPLOAD_ERR_OK 值:0; 没有错误发生,文件上传成功。
UPLOAD_ERR_INI_SIZE
值:1; 上传的文件超过了 php.ini 中 upload_max_filesize
选项限制的值。
UPLOAD_ERR_FORM_SIZE 值:2; 上传文件的大小超过了 HTML 表单中
MAX_FILE_SIZE
选项指定的值。
UPLOAD_ERR_PARTIAL
值:3;
文件只有部分被上传。
UPLOAD_ERR_NO_FILE
值:4; 没有文件被上传。
注意:这个错误信息是第一步上传的信息,也就是上传到临时文件夹的情况,而不是move或者copy的情况。
二、上传相关限制
2.1 客户端限制
<span><</span><span>form </span><span>action</span><span>="doAction2.php"</span><span> method</span><span>="post"</span><span> enctype</span><span>="multipart/form-data"</span><span>></span> <span><</span><span>input </span><span>type</span><span>="hidden"</span><span> name</span><span>="MAX_FILE_SIZE"</span><span> value</span><span>="101321"</span> <span>/></span><span> 请选择您要上传的文件: </span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile"</span><span> accept</span><span>="image/jpeg,image/gif,text/html"</span><span>/><</span><span>br</span><span>/></span> <span><</span><span>input </span><span>type</span><span>="submit"</span><span> value</span><span>="上传"</span><span>/></span> <span></</span><span>form</span><span>></span>
这里用input的属性对上传文件的大小和类型进行了限制,但是个人感觉:一,html代码是“可见的”;二,常不起作用(没找到原因,但因为第一个我也想放弃它,知道就好。
2.2 服务器端限制
主要限制大小和类型,再有就是方式。
<?<span>php </span><span>header</span>('content-type:text/html;charset=utf-8'<span>); </span><span>//</span><span>接受文件,临时文件信息</span> <span>$fileinfo</span>=<span>$_FILES</span>["myFile"];<span>//</span><span>降维操作</span> <span>$filename</span>=<span>$fileinfo</span>["name"<span>]; </span><span>$tmp_name</span>=<span>$fileinfo</span>["tmp_name"<span>]; </span><span>$size</span>=<span>$fileinfo</span>["size"<span>]; </span><span>$error</span>=<span>$fileinfo</span>["error"<span>]; </span><span>$type</span>=<span>$fileinfo</span>["type"<span>]; </span><span>//</span><span>服务器端设定限制</span> <span>$maxsize</span>=10485760;<span>//</span><span>10M,10*1024*1024</span> <span>$allowExt</span>=<span>array</span>('jpeg','jpg','png','tif');<span>//</span><span>允许上传的文件类型(拓展名</span> <span>$ext</span>=<span>pathinfo</span>(<span>$filename</span>,PATHINFO_EXTENSION);<span>//</span><span>提取上传文件的拓展名 //目的信息</span> <span>$path</span>="uploads"<span>; </span><span>if</span> (!<span>file_exists</span>(<span>$path</span>)) { <span>//</span><span>当目录不存在,就创建目录</span> <span>mkdir</span>(<span>$path</span>,0777,<span>true</span><span>); </span><span>chmod</span>(<span>$path</span>, 0777<span>); } </span><span>//</span><span>$destination=$path."/".$filename; //得到唯一的文件名!防止因为文件名相同而产生覆盖</span> <span>$uniName</span>=<span>md5</span>(<span>uniqid</span>(<span>microtime</span>(<span>true</span>),<span>true</span>)).<span>$ext</span>;<span>//</span><span>md5加密,uniqid产生唯一id,microtime做前缀</span> <span>if</span> (<span>$error</span>==0<span>) { </span><span>if</span> (<span>$size</span>><span>$maxsize</span><span>) { </span><span>exit</span>("上传文件过大!"<span>); } </span><span>if</span> (!<span>in_array</span>(<span>$ext</span>, <span>$allowExt</span><span>)) { </span><span>exit</span>("非法文件类型"<span>); } </span><span>if</span> (!<span>is_uploaded_file</span>(<span>$tmp_name</span><span>)) { </span><span>exit</span>("上传方式有误,请使用post方式"<span>); } </span><span>if</span> (@<span>move_uploaded_file</span>(<span>$tmp_name</span>, <span>$uniName</span>)) {<span>//</span><span>@错误抑制符,不让用户看到警告</span> <span>echo</span> "文件".<span>$filename</span>."上传成功!"<span>; }</span><span>else</span><span>{ </span><span>echo</span> "文件".<span>$filename</span>."上传失败!"<span>; } </span><span>//</span><span>判断是否为真实图片(防止伪装成图片的病毒一类的</span> <span>if</span> (!<span>getimagesize</span>(<span>$tmp_name</span>)) {<span>//</span><span>getimagesize真实返回数组,否则返回false</span> <span>exit</span>("不是真正的图片类型"<span>); } }</span><span>else</span><span>{ </span><span>switch</span> (<span>$error</span><span>){ </span><span>case</span> 1: <span>echo</span> "超过了上传文件的最大值,请上传2M以下文件"<span>; </span><span>break</span><span>; </span><span>case</span> 2: <span>echo</span> "上传文件过多,请一次上传20个及以下文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 3: <span>echo</span> "文件并未完全上传,请再次尝试!"<span>; </span><span>break</span><span>; </span><span>case</span> 4: <span>echo</span> "未选择上传文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 7: <span>echo</span> "没有临时文件夹"<span>; </span><span>break</span><span>; } }</span>
这里,具体实现都有注释,每一步其实都可以自己试试的,很有趣。
2.3 封装
函数
<?<span>php </span><span>function</span> uploadFile(<span>$fileInfo</span>,<span>$path</span>,<span>$allowExt</span>,<span>$maxSize</span><span>){ </span><span>$filename</span>=<span>$fileInfo</span>["name"<span>]; </span><span>$tmp_name</span>=<span>$fileInfo</span>["tmp_name"<span>]; </span><span>$size</span>=<span>$fileInfo</span>["size"<span>]; </span><span>$error</span>=<span>$fileInfo</span>["error"<span>]; </span><span>$type</span>=<span>$fileInfo</span>["type"<span>]; </span><span>//</span><span>服务器端设定限制</span> <span>$ext</span>=<span>pathinfo</span>(<span>$filename</span>,<span>PATHINFO_EXTENSION); </span><span>//</span><span>目的信息</span> <span>if</span> (!<span>file_exists</span>(<span>$path</span><span>)) { </span><span>mkdir</span>(<span>$path</span>,0777,<span>true</span><span>); </span><span>chmod</span>(<span>$path</span>, 0777<span>); } </span><span>$uniName</span>=<span>md5</span>(<span>uniqid</span>(<span>microtime</span>(<span>true</span>),<span>true</span>)).'.'.<span>$ext</span><span>; </span><span>$destination</span>=<span>$path</span>."/".<span>$uniName</span><span>; </span><span>if</span> (<span>$error</span>==0<span>) { </span><span>if</span> (<span>$size</span>><span>$maxSize</span><span>) { </span><span>exit</span>("上传文件过大!"<span>); } </span><span>if</span> (!<span>in_array</span>(<span>$ext</span>, <span>$allowExt</span><span>)) { </span><span>exit</span>("非法文件类型"<span>); } </span><span>if</span> (!<span>is_uploaded_file</span>(<span>$tmp_name</span><span>)) { </span><span>exit</span>("上传方式有误,请使用post方式"<span>); } </span><span>//</span><span>判断是否为真实图片(防止伪装成图片的病毒一类的</span> <span>if</span> (!<span>getimagesize</span>(<span>$tmp_name</span>)) {<span>//</span><span>getimagesize真实返回数组,否则返回false</span> <span>exit</span>("不是真正的图片类型"<span>); } </span><span>if</span> (@<span>move_uploaded_file</span>(<span>$tmp_name</span>, <span>$destination</span>)) {<span>//</span><span>@错误抑制符,不让用户看到警告</span> <span>echo</span> "文件".<span>$filename</span>."上传成功!"<span>; }</span><span>else</span><span>{ </span><span>echo</span> "文件".<span>$filename</span>."上传失败!"<span>; } }</span><span>else</span><span>{ </span><span>switch</span> (<span>$error</span><span>){ </span><span>case</span> 1: <span>echo</span> "超过了上传文件的最大值,请上传2M以下文件"<span>; </span><span>break</span><span>; </span><span>case</span> 2: <span>echo</span> "上传文件过多,请一次上传20个及以下文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 3: <span>echo</span> "文件并未完全上传,请再次尝试!"<span>; </span><span>break</span><span>; </span><span>case</span> 4: <span>echo</span> "未选择上传文件!"<span>; </span><span>break</span><span>; </span><span>case</span> 7: <span>echo</span> "没有临时文件夹"<span>; </span><span>break</span><span>; } } </span><span>return</span> <span>$destination</span><span>; }</span>
调用
<?<span>php </span><span>header</span>('content-type:text/html;charset=utf-8'<span>); </span><span>$fileInfo</span>=<span>$_FILES</span>["myFile"<span>]; </span><span>$maxSize</span>=10485760;<span>//</span><span>10M,10*1024*1024</span> <span>$allowExt</span>=<span>array</span>('jpeg','jpg','png','tif'<span>); </span><span>$path</span>="uploads"<span>; </span><span>include_once</span> 'upFunc.php'<span>; uploadFile(</span><span>$fileInfo</span>, <span>$path</span>, <span>$allowExt</span>, <span>$maxSize</span>);
三、多文件的上传实现
3.1 利用单文件封装
<span><!</span><span>DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"</span><span>></span> <span><</span><span>html</span><span>></span> <span><</span><span>head</span><span>></span> <span><</span><span>meta </span><span>http-equiv</span><span>="Content-Type"</span><span> content</span><span>="text/html; charset=UTF-8"</span><span>></span> <span><</span><span>title</span><span>></span>Insert title here<span></</span><span>title</span><span>></span> <span></</span><span>head</span><span>></span> <span><</span><span>body</span><span>></span> <span><</span><span>form </span><span>action</span><span>="doAction5.php"</span><span> method</span><span>="post"</span><span> enctype</span><span>="multipart/form-data"</span><span>></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile1"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile2"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile3"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile4"</span> <span>/><</span><span>br</span><span>/></span> <span><</span><span>input </span><span>type</span><span>="submit"</span><span> value</span><span>="上传"</span><span>/></span> <span></</span><span>form</span><span>></span> <span></</span><span>body</span><span>></span> <span></</span><span>html</span><span>></span>
<?<span>php </span><span>//</span><span>print_r($_FILES);</span> <span>header</span>('content-type:text/html;charset=utf-8'<span>); </span><span>include_once</span> 'upFunc.php'<span>; </span><span>foreach</span> (<span>$_FILES</span> <span>as</span> <span>$fileInfo</span><span>){ </span><span>$file</span>[]=uploadFile(<span>$fileInfo</span><span>); }</span>
这里的思路,从print_r($_FILES)中去找,打印出来看到是个二维数组,很简单,遍历去用就好了!
上面那个function的定义改一下,给定一些默认值
<span>function</span> uploadFile(<span>$fileInfo</span>,<span>$path</span>="uploads",<span>$allowExt</span>=<span>array</span>('jpeg','jpg','png','tif'),<span>$maxSize</span>=10485760){
这样子,简单是简单,但遇到一些问题。
正常的上传4个图片是没问题,但要是中间激活了函数中的exit,就会立即停止,导致其他图片也无法上传。
3.2 升级版封装
旨在实现针对多个或单个文件上传的封装
首先这样子写个静态文件
<span><!</span><span>DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"</span><span>></span> <span><</span><span>html</span><span>></span> <span><</span><span>head</span><span>></span> <span><</span><span>meta </span><span>http-equiv</span><span>="Content-Type"</span><span> content</span><span>="text/html; charset=UTF-8"</span><span>></span> <span><</span><span>title</span><span>></span>Insert title here<span></</span><span>title</span><span>></span> <span></</span><span>head</span><span>></span> <span><</span><span>body</span><span>></span> <span><</span><span>form </span><span>action</span><span>="doAction5.php"</span><span> method</span><span>="post"</span><span> enctype</span><span>="multipart/form-data"</span><span>></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile[]"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile[]"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile[]"</span> <span>/><</span><span>br</span><span>/></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile[]"</span> <span>/><</span><span>br</span><span>/></span> <span><</span><span>input </span><span>type</span><span>="submit"</span><span> value</span><span>="上传"</span><span>/></span> <span></</span><span>form</span><span>></span> <span></</span><span>body</span><span>></span> <span></</span><span>html</span><span>></span>
打印一下$_FILES
<span>Array ( [myFile] => Array ( [name] => Array ( [0] => test32.png [1] => test32.png [2] => 333.png [3] => test41.png ) [type] => Array ( [0] => image/png [1] => image/png [2] => image/png [3] => image/png ) [tmp_name] => Array ( [0] => D:\wamp\tmp\php831C.tmp [1] => D:\wamp\tmp\php834C.tmp [2] => D:\wamp\tmp\php837C.tmp [3] => D:\wamp\tmp\php83BB.tmp ) [error] => Array ( [0] => 0 [1] => 0 [2] => 0 [3] => 0 ) [size] => Array ( [0] => 46174 [1] => 46174 [2] => 34196 [3] => 38514 ) ) )</span>
可以得到一个三维数组。
复杂是复杂了,但复杂的有规律,各项数值都在一起了,很方便我们取值!!
所以先得到文件信息,变成单文件处理那种信息
<span>function</span><span> getFiles(){ </span><span>$i</span>=0<span>; </span><span>foreach</span>(<span>$_FILES</span> <span>as</span> <span>$file</span><span>){ </span><span>if</span>(<span>is_string</span>(<span>$file</span>['name'])){ <span>//</span><span>单文件判定</span> <span>$files</span>[<span>$i</span>]=<span>$file</span><span>; </span><span>$i</span>++<span>; }</span><span>elseif</span>(<span>is_array</span>(<span>$file</span>['name'<span>])){ </span><span>foreach</span>(<span>$file</span>['name'] <span>as</span> <span>$key</span>=><span>$val</span>){ <span>//</span><span>我的天,这个$key用的diao</span> <span>$files</span>[<span>$i</span>]['name']=<span>$file</span>['name'][<span>$key</span><span>]; </span><span>$files</span>[<span>$i</span>]['type']=<span>$file</span>['type'][<span>$key</span><span>]; </span><span>$files</span>[<span>$i</span>]['tmp_name']=<span>$file</span>['tmp_name'][<span>$key</span><span>]; </span><span>$files</span>[<span>$i</span>]['error']=<span>$file</span>['error'][<span>$key</span><span>]; </span><span>$files</span>[<span>$i</span>]['size']=<span>$file</span>['size'][<span>$key</span><span>]; </span><span>$i</span>++<span>; } } } </span><span>return</span> <span>$files</span><span>; }</span>
然后之前的那种exit错误,就把exit改一下就好了,这里用res
<span>function</span> uploadFile(<span>$fileInfo</span>,<span>$path</span>='./uploads',<span>$flag</span>=<span>true</span>,<span>$maxSize</span>=1048576,<span>$allowExt</span>=<span>array</span>('jpeg','jpg','png','gif'<span>)){ </span><span>//</span><span>$flag=true; //$allowExt=array('jpeg','jpg','gif','png'); //$maxSize=1048576;//1M //判断错误号</span> <span>$res</span>=<span>array</span><span>(); </span><span>if</span>(<span>$fileInfo</span>['error']===<span>UPLOAD_ERR_OK){ </span><span>//</span><span>检测上传得到小</span> <span>if</span>(<span>$fileInfo</span>['size']><span>$maxSize</span><span>){ </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'上传文件过大'<span>; } </span><span>$ext</span>=getExt(<span>$fileInfo</span>['name'<span>]); </span><span>//</span><span>检测上传文件的文件类型</span> <span>if</span>(!<span>in_array</span>(<span>$ext</span>,<span>$allowExt</span><span>)){ </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'非法文件类型'<span>; } </span><span>//</span><span>检测是否是真实的图片类型</span> <span>if</span>(<span>$flag</span><span>){ </span><span>if</span>(!<span>getimagesize</span>(<span>$fileInfo</span>['tmp_name'<span>])){ </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'不是真实图片类型'<span>; } } </span><span>//</span><span>检测文件是否是通过HTTP POST上传上来的</span> <span>if</span>(!<span>is_uploaded_file</span>(<span>$fileInfo</span>['tmp_name'<span>])){ </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'文件不是通过HTTP POST方式上传上来的'<span>; } </span><span>if</span>(<span>$res</span>) <span>return</span> <span>$res</span><span>; </span><span>//</span><span>$path='./uploads';</span> <span>if</span>(!<span>file_exists</span>(<span>$path</span><span>)){ </span><span>mkdir</span>(<span>$path</span>,0777,<span>true</span><span>); </span><span>chmod</span>(<span>$path</span>,0777<span>); } </span><span>$uniName</span>=<span>getUniName(); </span><span>$destination</span>=<span>$path</span>.'/'.<span>$uniName</span>.'.'.<span>$ext</span><span>; </span><span>if</span>(!<span>move_uploaded_file</span>(<span>$fileInfo</span>['tmp_name'],<span>$destination</span><span>)){ </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'文件移动失败'<span>; } </span><span>$res</span>['mes']=<span>$fileInfo</span>['name'].'上传成功'<span>; </span><span>$res</span>['dest']=<span>$destination</span><span>; </span><span>return</span> <span>$res</span><span>; }</span><span>else</span><span>{ </span><span>//</span><span>匹配错误信息</span> <span>switch</span> (<span>$fileInfo</span> ['error'<span>]) { </span><span>case</span> 1 : <span>$res</span>['mes'] = '上传文件超过了PHP配置文件中upload_max_filesize选项的值'<span>; </span><span>break</span><span>; </span><span>case</span> 2 : <span>$res</span>['mes'] = '超过了表单MAX_FILE_SIZE限制的大小'<span>; </span><span>break</span><span>; </span><span>case</span> 3 : <span>$res</span>['mes'] = '文件部分被上传'<span>; </span><span>break</span><span>; </span><span>case</span> 4 : <span>$res</span>['mes'] = '没有选择上传文件'<span>; </span><span>break</span><span>; </span><span>case</span> 6 : <span>$res</span>['mes'] = '没有找到临时目录'<span>; </span><span>break</span><span>; </span><span>case</span> 7 : <span>case</span> 8 : <span>$res</span>['mes'] = '系统错误'<span>; </span><span>break</span><span>; } </span><span>return</span> <span>$res</span><span>; } }</span>
里面封装了两个小的
<span>function</span> getExt(<span>$filename</span><span>){ </span><span>return</span> <span>strtolower</span>(<span>pathinfo</span>(<span>$filename</span>,<span>PATHINFO_EXTENSION)); } </span><span>/*</span><span>* * 产生唯一字符串 * @return string </span><span>*/</span> <span>function</span><span> getUniName(){ </span><span>return</span> <span>md5</span>(<span>uniqid</span>(<span>microtime</span>(<span>true</span>),<span>true</span><span>)); }</span>
然后静态中,用multiple属性实现多个文件的输入;
<span><!</span><span>DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"</span><span>></span> <span><</span><span>html</span><span>></span> <span><</span><span>head</span><span>></span> <span><</span><span>meta </span><span>http-equiv</span><span>="Content-Type"</span><span> content</span><span>="text/html; charset=UTF-8"</span><span>></span> <span><</span><span>title</span><span>></span>Insert title here<span></</span><span>title</span><span>></span> <span></</span><span>head</span><span>></span> <span><</span><span>body</span><span>></span> <span><</span><span>form </span><span>action</span><span>="doAction6.php"</span><span> method</span><span>="POST"</span><span> enctype</span><span>="multipart/form-data"</span><span>></span><span> 请选择您要上传的文件:</span><span><</span><span>input </span><span>type</span><span>="file"</span><span> name</span><span>="myFile[]"</span><span> multiple</span><span>='multiple' </span><span>/><</span><span>br</span><span>/></span> <span><</span><span>input </span><span>type</span><span>="submit"</span><span> value</span><span>="上传"</span><span>/></span> <span></</span><span>form</span><span>></span> <span></</span><span>body</span><span>></span> <span></</span><span>html</span><span>></span>
doAction6
<?<span>php </span><span>//</span><span>print_r($_FILES);</span> <span>header</span>("content-type:text/html;charset=utf-8"<span>); </span><span>require_once</span> 'upFunc2.php'<span>; </span><span>require_once</span> 'common.func.php'<span>; </span><span>$files</span>=<span>getFiles(); </span><span>//</span><span> print_r($files);</span> <span>foreach</span>(<span>$files</span> <span>as</span> <span>$fileInfo</span><span>){ </span><span>$res</span>=uploadFile(<span>$fileInfo</span><span>); </span><span>echo</span> <span>$res</span>['mes'],'<br/>'<span>; </span><span>$uploadFiles</span>[]=@<span>$res</span>['dest'<span>]; } </span><span>$uploadFiles</span>=<span>array_values</span>(<span>array_filter</span>(<span>$uploadFiles</span><span>)); </span><span>//</span><span>print_r($uploadFiles);</span>
这样子的几个文件,就实现比较强大的面向过程的上传文件的功能(学的叫一个心酸。。。);
四、面向对象的文件上传
(不是很写的动了。。。先粘过来,再说吧。。。
<?<span>php </span><span>class</span><span> upload{ </span><span>protected</span> <span>$fileName</span><span>; </span><span>protected</span> <span>$maxSize</span><span>; </span><span>protected</span> <span>$allowMime</span><span>; </span><span>protected</span> <span>$allowExt</span><span>; </span><span>protected</span> <span>$uploadPath</span><span>; </span><span>protected</span> <span>$imgFlag</span><span>; </span><span>protected</span> <span>$fileInfo</span><span>; </span><span>protected</span> <span>$error</span><span>; </span><span>protected</span> <span>$ext</span><span>; </span><span>/*</span><span>* * @param string $fileName * @param string $uploadPath * @param string $imgFlag * @param number $maxSize * @param array $allowExt * @param array $allowMime </span><span>*/</span> <span>public</span> <span>function</span> __construct(<span>$fileName</span>='myFile',<span>$uploadPath</span>='./uploads',<span>$imgFlag</span>=<span>true</span>,<span>$maxSize</span>=5242880,<span>$allowExt</span>=<span>array</span>('jpeg','jpg','png','gif'),<span>$allowMime</span>=<span>array</span>('image/jpeg','image/png','image/gif'<span>)){ </span><span>$this</span>->fileName=<span>$fileName</span><span>; </span><span>$this</span>->maxSize=<span>$maxSize</span><span>; </span><span>$this</span>->allowMime=<span>$allowMime</span><span>; </span><span>$this</span>->allowExt=<span>$allowExt</span><span>; </span><span>$this</span>->uploadPath=<span>$uploadPath</span><span>; </span><span>$this</span>->imgFlag=<span>$imgFlag</span><span>; </span><span>$this</span>->fileInfo=<span>$_FILES</span>[<span>$this</span>-><span>fileName]; } </span><span>/*</span><span>* * 检测上传文件是否出错 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkError(){ </span><span>if</span>(!<span>is_null</span>(<span>$this</span>-><span>fileInfo)){ </span><span>if</span>(<span>$this</span>->fileInfo['error']>0<span>){ </span><span>switch</span>(<span>$this</span>->fileInfo['error'<span>]){ </span><span>case</span> 1: <span>$this</span>->error='超过了PHP配置文件中upload_max_filesize选项的值'<span>; </span><span>break</span><span>; </span><span>case</span> 2: <span>$this</span>->error='超过了表单中MAX_FILE_SIZE设置的值'<span>; </span><span>break</span><span>; </span><span>case</span> 3: <span>$this</span>->error='文件部分被上传'<span>; </span><span>break</span><span>; </span><span>case</span> 4: <span>$this</span>->error='没有选择上传文件'<span>; </span><span>break</span><span>; </span><span>case</span> 6: <span>$this</span>->error='没有找到临时目录'<span>; </span><span>break</span><span>; </span><span>case</span> 7: <span>$this</span>->error='文件不可写'<span>; </span><span>break</span><span>; </span><span>case</span> 8: <span>$this</span>->error='由于PHP的扩展程序中断文件上传'<span>; </span><span>break</span><span>; } </span><span>return</span> <span>false</span><span>; }</span><span>else</span><span>{ </span><span>return</span> <span>true</span><span>; } }</span><span>else</span><span>{ </span><span>$this</span>->error='文件上传出错'<span>; </span><span>return</span> <span>false</span><span>; } } </span><span>/*</span><span>* * 检测上传文件的大小 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkSize(){ </span><span>if</span>(<span>$this</span>->fileInfo['size']><span>$this</span>-><span>maxSize){ </span><span>$this</span>->error='上传文件过大'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>return</span> <span>true</span><span>; } </span><span>/*</span><span>* * 检测扩展名 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkExt(){ </span><span>$this</span>->ext=<span>strtolower</span>(<span>pathinfo</span>(<span>$this</span>->fileInfo['name'],<span>PATHINFO_EXTENSION)); </span><span>if</span>(!<span>in_array</span>(<span>$this</span>->ext,<span>$this</span>-><span>allowExt)){ </span><span>$this</span>->error='不允许的扩展名'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>return</span> <span>true</span><span>; } </span><span>/*</span><span>* * 检测文件的类型 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkMime(){ </span><span>if</span>(!<span>in_array</span>(<span>$this</span>->fileInfo['type'],<span>$this</span>-><span>allowMime)){ </span><span>$this</span>->error='不允许的文件类型'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>return</span> <span>true</span><span>; } </span><span>/*</span><span>* * 检测是否是真实图片 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkTrueImg(){ </span><span>if</span>(<span>$this</span>-><span>imgFlag){ </span><span>if</span>(!@<span>getimagesize</span>(<span>$this</span>->fileInfo['tmp_name'<span>])){ </span><span>$this</span>->error='不是真实图片'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>return</span> <span>true</span><span>; } } </span><span>/*</span><span>* * 检测是否通过HTTP POST方式上传上来的 * @return boolean </span><span>*/</span> <span>protected</span> <span>function</span><span> checkHTTPPost(){ </span><span>if</span>(!<span>is_uploaded_file</span>(<span>$this</span>->fileInfo['tmp_name'<span>])){ </span><span>$this</span>->error='文件不是通过HTTP POST方式上传上来的'<span>; </span><span>return</span> <span>false</span><span>; } </span><span>return</span> <span>true</span><span>; } </span><span>/*</span><span>* *显示错误 </span><span>*/</span> <span>protected</span> <span>function</span><span> showError(){ </span><span>exit</span>('<span>$this</span>->error.'</span>'<span>); } </span><span>/*</span><span>* * 检测目录不存在则创建 </span><span>*/</span> <span>protected</span> <span>function</span><span> checkUploadPath(){ </span><span>if</span>(!<span>file_exists</span>(<span>$this</span>-><span>uploadPath)){ </span><span>mkdir</span>(<span>$this</span>->uploadPath,0777,<span>true</span><span>); } } </span><span>/*</span><span>* * 产生唯一字符串 * @return string </span><span>*/</span> <span>protected</span> <span>function</span><span> getUniName(){ </span><span>return</span> <span>md5</span>(<span>uniqid</span>(<span>microtime</span>(<span>true</span>),<span>true</span><span>)); } </span><span>/*</span><span>* * 上传文件 * @return string </span><span>*/</span> <span>public</span> <span>function</span><span> uploadFile(){ </span><span>if</span>(<span>$this</span>->checkError()&&<span>$this</span>->checkSize()&&<span>$this</span>->checkExt()&&<span>$this</span>->checkMime()&&<span>$this</span>->checkTrueImg()&&<span>$this</span>-><span>checkHTTPPost()){ </span><span>$this</span>-><span>checkUploadPath(); </span><span>$this</span>->uniName=<span>$this</span>-><span>getUniName(); </span><span>$this</span>->destination=<span>$this</span>->uploadPath.'/'.<span>$this</span>->uniName.'.'.<span>$this</span>-><span>ext; </span><span>if</span>(@<span>move_uploaded_file</span>(<span>$this</span>->fileInfo['tmp_name'], <span>$this</span>-><span>destination)){ </span><span>return</span> <span>$this</span>-><span>destination; }</span><span>else</span><span>{ </span><span>$this</span>->error='文件移动失败'<span>; </span><span>$this</span>-><span>showError(); } }</span><span>else</span><span>{ </span><span>$this</span>-><span>showError(); } } }</span>
<?<span>php </span><span>header</span>('content-type:text/html;charset=utf-8'<span>); </span><span>require_once</span> 'upload.class.php'<span>; </span><span>$upload</span>=<span>new</span> upload('myFile1','imooc'<span>); </span><span>$dest</span>=<span>$upload</span>-><span>uploadFile(); </span><span>echo</span> <span>$dest</span>;
四、下载
对于浏览器不识别的,可以直接下载,但对于能识别的,需要多一两步
<span><!</span><span>DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</span><span>></span> <span><</span><span>html </span><span>xmlns</span><span>="http://www.w3.org/1999/xhtml"</span><span>></span> <span><</span><span>head</span><span>></span> <span><</span><span>meta </span><span>http-equiv</span><span>="Content-Type"</span><span> content</span><span>="text/html; charset=UTF-8"</span> <span>/></span> <span><</span><span>title</span><span>></span>Insert title here<span></</span><span>title</span><span>></span> <span></</span><span>head</span><span>></span> <span><</span><span>body</span><span>></span> <span><</span><span>a </span><span>href</span><span>="1.rar"</span><span>></span>下载1.rar<span></</span><span>a</span><span>></span> <span><</span><span>br </span><span>/></span> <span><</span><span>a </span><span>href</span><span>="1.jpg"</span><span>></span>下载1.jpg<span></</span><span>a</span><span>></span> <span><</span><span>br </span><span>/></span> <span><</span><span>a </span><span>href</span><span>="doDownload.php?filename=1.jpg"</span><span>></span>通过程序下载1.jpg<span></</span><span>a</span><span>></span> <span><</span><span>br </span><span>/></span> <span><</span><span>a </span><span>href</span><span>="doDownload.php?filename=../upload/nv.jpg"</span><span>></span>下载nv.jpg<span></</span><span>a</span><span>></span> <span><?</span><span>php </span><span>?></span> <span></</span><span>body</span><span>></span> <span></</span><span>html</span><span>></span>
<?<span>php </span><span>$filename</span>=<span>$_GET</span>['filename'<span>]; </span><span>header</span>('content-disposition:attachment;filename='.<span>basename</span>(<span>$filename</span><span>)); </span><span>header</span>('content-length:'.<span>filesize</span>(<span>$filename</span><span>)); </span><span>readfile</span>(<span>$filename</span>);
------------------总结-----------------------
<form action="doAction.php" method="post" enctype="multipart/form-data">
二维数组的降维处理;
$_FILES变量
move_upload_file();copy();
tmp_name临时文件;
拓展名的提取;
真实图片的验证;
唯一文件名的生成;
函数封装以及调用;
利用单个文件函数实现多文件上传;
小功能的封装;
多文件的遍历;
面向对象的开发过程;
下载;
----------------------------------------
妈蛋啊。。。。。。。。。