文件上传原理
将客户端的文件上传到服务器端,再将服务器端的临时文件移动到指定目录即可
客户端配置
表单页面index.html
表单的发送方式为POST
表单数据编码为multipart/form-data
index.html文件
<html> <head> <metacharset="UTF-8"> <title>文件上传页面</title> </head> <body> <formaction="upload.php"method="post"enctype="multipart/form-data"> <inputtype="file"name="file"> <buttontype="submit">上传</button> </form> </body> </html>
upload.php文件
<?php
print_r($_FILES);
打印结果:
Array
(
[file]=>Array
(
[name]=>1.jpg
[type]=>image/jpeg
[tmp_name]=>D:\temp\phpFD7D.tmp
[error]=>0
[size]=>176943
)
)
$_FILES中保存着上传文件的信息
name:上传文件的名称
type:上传文件的MIME类型
tmp_name:上传到服务器上的临时文件名
error:上传文件的错误号
size:上传文件的大小
保存上传的文件
将服务器上的临时文件移动指定目录下
move_uploaded_file
<?php $unique_name=md5(uniqid(microtime(true),true));//唯一文件名 $ext=pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION); move_uploaded_file($_FILES['file']['tmp_name'],'uploads'.DIRECTORY_SEPARATOR.$unique_name.'.'.$ext); copy <?php copy($_FILES['file']['tmp_name'],'uploads'.DIRECTORY_SEPARATOR.$_FILES['file']['name']);
文件上传配置
服务器端配置php.ini
file_uploads=On#支持http上传 upload_tmp_dir=#临时文件保存目录 upload_max_filesize=2M#允许上传文件的最大值 max_file_uploads=20#允许一次上传的最大文件数 post_max_size=8M#POST方式发送数据的最大值 max_execution_time=-1#设置脚本被解析器终止之前允许的最大执行时间,单位为秒 max_input_time=60#脚本解析输入数据允许的最大时间,单位为秒 max_input_nesting_level=64#设置输入变量的嵌套深度 max_input_vars=1000#最多接受输入的变量 memory_limit=128M#最大单线程的独立内存使用量
错误信息说明
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,没有文件被上传 UPLOAD_ERR_NO_TMP_DIR#值为6,找不到临时文件夹 UPLOAD_ERR_CANT_WRITE#值为7,文件写入失败 UPLOAD_ERR_EXTENSION#值为8,上传的文件被PHP扩展程序中断
上传文件限制
客户端限制
通过表单隐藏域限制上传文件的最大值
<inputtype="hidden"name="MAX_FILE_SIZE"value="字节数">
通过accept属性限制上传文件类型
<inputtype="file"name="file"accept="image/gif,image/jpeg">
服务端限制
限制上传文件大小
<?php $size=2048; if($_FILES['file']['size']>$size){ echo'文件太大'; }
限制上传文件类型
<?php $ext=['jpeg','png','gif']; if(!in_array(pathinfo($_FILES['file']['name'],PATHINFO_EXTENSION),$ext)){ echo'非法文件类型'; }
检测是否为真实的图片类型
<?php if(!getimagesize($_FILES['file']['tmp_name'])){ echo'不是真实的图片类型'; }
检测是否为HTTPPOST方式上传
<?php if(!is_uploaded_file($_FILES['file']['tmp_name'])){ echo'非法上传'; }
文件上传的封装
Upload.class.php文件
<?php classUpload { protected$filename; protected$savePath; protected$maxSize; protected$allowExt; protected$allowMime; protected$checkImage; protected$fileInfo; protected$ext; protected$uniName; protected$destination; protected$error; publicfunction__construct($filename='file',$savePath='uploads',$maxSize=2097152,$allowExt=['jpeg','jpg','png','gif'],$allowMime=['image/jpeg','image/png','image/gif'],$checkImage=true) { $this->filename=$filename; $this->savePath=$savePath; $this->maxSize=$maxSize; $this->allowExt=$allowExt; $this->allowMime=$allowMime; $this->checkImage=$checkImage; $this->fileInfo=$_FILES[$this->filename]; } publicfunctionupload_file() { if($this->check_error()&&$this->check_size()&&$this->check_ext()&&$this->check_mime()&&$this->check_image()&&$this->check_http_post()){ $this->check_save_path(); $this->get_unique_name(); $this->destination=$this->savePath.DIRECTORY_SEPARATOR.$this->uniName.'.'.$this->ext; if(@move_uploaded_file($this->fileInfo['tmp_name'],$this->destination)){ return$this->destination; }else{ $this->error='文件移动失败'; $this->show_error(); returnfalse; } }else{ $this->show_error(); returnfalse; } } /** *检测上传文件是否出错 *@returnbool */ privatefunctioncheck_error() { if(!is_null($this->fileInfo)){ if($this->fileInfo['error']>0){ switch($this->fileInfo['error']){ case1: $this->error='超过了PHP配置文件中upload_max_filesize选项的值'; break; case2: $this->error='超过了表单中MAX_FILE_SIZE设置的值'; break; case3: $this->error='文件部分被上传'; break; case4: $this->error='没有选择上传文件'; break; case6: $this->error='没有找到临时目录'; break; case7: $this->error='文件不可写'; break; case8: $this->error='由于PHP的扩展程序中断文件上传'; break; } returnfalse; }else{ returntrue; } }else{ $this->error='文件上传出错'; returnfalse; } } /** *检测上传文件的大小 *@returnbool */ privatefunctioncheck_size() { if($this->fileInfo['size']>$this->maxSize){ $this->error='上传文件过大'; returnfalse; } returntrue; } /** *检测上传文件的扩展名 *@returnbool */ privatefunctioncheck_ext() { $this->ext=strtolower(pathinfo($this->fileInfo['name'],PATHINFO_EXTENSION)); if(!in_array($this->ext,$this->allowExt)){ $this->error='不允许的扩展名'; returnfalse; } returntrue; } /** *检测上传文件的类型 *@returnbool */ privatefunctioncheck_mime() { if(!in_array($this->fileInfo['type'],$this->allowMime)){ $this->error='不允许的文件类型'; returnfalse; } returntrue; } /** *检测是否真实图片 *@returnbool */ privatefunctioncheck_image() { if($this->checkImage){ if(!@getimagesize($this->fileInfo['tmp_name'])){ $this->error='不是真实图片'; returnfalse; } } returntrue; } /** *检测是否通过HTTPPOST方式上传 *@returnbool */ privatefunctioncheck_http_post() { if(!is_uploaded_file($this->fileInfo['tmp_name'])){ $this->error='文件不是通过HTTPPOST方式上传'; returnfalse; } returntrue; } /** *检测文件保存目录,不存在则创建 */ privatefunctioncheck_save_path() { if(!file_exists($this->savePath)){ mkdir($this->savePath,0777,true); } } /** *产生唯一字符串 */ privatefunctionget_unique_name() { $this->uniName=md5(uniqid(microtime(true),true)); } /** *输出错误信息 */ privatefunctionshow_error() { exit($this->error); } }
文件下载
<ahref=”download.php?filename=1.jpg”>下载</a>
download.php文件
<?php $filename=$_GET['filename']; header('content-disposition:attachment;filename='.basename($filename)); header('content-length:'.filesize($filename)); readfile($filename);