文件上传模块

上传原理

 

将客户端文件上传到服务器端,再将服务器端的文件(临时文件)移动到指定目录即可。

 

通过学习文件上传,你将透过使用的现象看到文件上传的本质!

 

 

1. 上传的实现

1. 1 客户端配置

选择文件上传页面(表单页面)

 

下面两个 条件 缺一不可:

1 发送方式为POST

2 添加enctype="multipart/form-data"属性

index.php代码如下:

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

 <meta name="format-detection" content="telephone=no" />

<title>文件上传</title>

<meta charset="utf-8" />

</head>

<body>

<form action="upload.php"  method="post" enctype="multipart/form-data" >

请选择您要上传的文件:<br/>

<input type="file" name="myFile" /><br/>

<input type="submit" value="上传"/>

</form>

</body>

</html>

注:关键就是form的属性;另外就是input 中用到了type="file"这一点

 

 

1.2服务 端配置

处理 上传文件

处理 流程如下

1 ) 获得上传页面传递的$FILES

2 ) 将服务器的临时文件移动到指定位置

方法一:move_upload_file($tmp_name,$destination)

方法二:copy($src,$des)

注意:move相当于剪切;而copy则临时文件还在

3 ) 根据$error的值,提示不同信息 , 进行相应处理

 

upload.php代码如下:

<?php

header("Content-type:text/html;charset=utf-8");

//文件上传处理程序

//$_FILES:文件上传变量

$filename=$_FILES['myFile']['name'];

$type=$_FILES['myFile']['type'];

$tmp_name=$_FILES['myFile']['tmp_name'];

$size=$_FILES['myFile']['size'];

$error=$_FILES['myFile']['error'];

 

//将服务器上的临时文件移动到指定位置

//方法一move_upload_file($tmp_name,$destination)

//move_uploaded_file($tmp_name, "uploads/".$filename);//文件夹应提前建立好,不然报错

//方法二copy($src,$des)

//以上两个函数都是成功返回真,否则返回false

//copy($tmp_name, "copies/".$filename);

//注意,不能两个方法都对临时文件进行操作,临时文件似乎操作完就没了,我们试试反过来

copy($tmp_name, "copies/".$filename);

move_uploaded_file($tmp_name, "uploads/".$filename);

//能够实现,说明move那个函数基本上相当于剪切;copy就是copy,临时文件还在

 

//另外,错误信息也是不一样的,遇到错误可以查看或者直接报告给用户

if ($error===0) {

  echo "上传成功!";

}else{

  switch ($error){

    case 1:

      echo "超过了上传文件的最大值,请上传2M以下文件";

      break;

    case 2:

      echo "上传文件过多,请一次上传20个及以下文件!";

      break;

    case 3:

      echo "文件并未完全上传,请再次尝试!";

      break;

    case 4:

      echo "未选择上传文件!";

      break;

    case 5:

      echo "上传文件为0";

      break;

  }

}

>

 

 

注:需要在upload.php的同级目录里新建一个uploads文件夹用于存放上传的图片,不然会报错上面的var_dump($_FILES);可以在测试时候对文件上传成功与否进行判断,如果成功上传,返回文件信息数组 , 如 :

array(1){

["myflie"]=>

array(5){

["name"]=>string(37)"xxxxxxxx.jpg"

["type"]=>string(10)"image/jpeg"

["tmp_name"]=>string(44)"C:\Users\win7\xxxxxx\xxxx\xxx\xxx.tmp

["error"]=>int(0)

["size"]=>int(13767)

}

}

得到是一个二维数组,关键有两个:tmp_name临时文件名;error报错信息(代号,后面可以利用);

 

报错原因

基本上都是超过或者不符合服务器关于上传文件的配置,那么服务器端配置有哪些呢?

 

先考虑上传我们用了什么?POSTupload

 

所以在php.ini中找这么几项:

 

    file_upload:On

 

    upload_tmp_dir=——临时文件保存目录;

 

    upload_max_filesize=2M

 

    max_file_uploads=20——允许一次上传的最大文件数量

 

    post_max_size=8M——post方式发送数据的最大值

 

其他相关配置

 

    max_exectuion_time=-1——最大执行时间,避免程序不好占用服务器资源;

 

    max_input_time=60

 

    max_input_nesting_level=64——输入嵌套深度;

 

    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; 没有文件被上传。

 

注:这个错误信息是第一步上传的信息,也就是上传到临时文件夹的情况,而不是move或者copy的情况。

 

 

下面从客户端和服务器端实现两个限制

 

客户端限制

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

 <meta name="format-detection" content="telephone=no" />

<title>文件上传(客户端限制)</title>

<meta charset="utf-8" />

</head>

<body>

<form action="upload2.php" method="post" enctype="multipart/form-data">

<input type="hidden" name="MAX_FILE_SIZE" value="101321" />

请选择您要上传的文件:

<input type="file" name="myFile" accept="image/jpeg,image/gif,text/html"/><br/>

<input type="submit" value="上传"/>

</form>

</body>

</html>

 

这里用input的属性对上传文件的大小和类型进行了限制,但是个人感觉

1.html代码是“可见的”

2.常不起作用。

 

服务器端限制

<?php

header('content-type:text/html;charset=utf-8');

//接受文件,临时文件信息

$fileinfo=$_FILES["myFile"];//降维操作

$filename=$fileinfo["name"];

$tmp_name=$fileinfo["tmp_name"];

$size=$fileinfo["size"];

$error=$fileinfo["error"];

$type=$fileinfo["type"];

 

//服务器端设定限制

$maxsize=10485760;//10M,10*1024*1024

$allowExt=array('jpeg','jpg','png','tif');//允许上传的文件类型(拓展名

$ext=pathinfo($filename,PATHINFO_EXTENSION);//提取上传文件的拓展名

//目标存放文件夹

$path="uploads";

if (!file_exists($path)) {  //当目录不存在,就创建目录

  mkdir($path,0777,true);//创建目录

  chmod($path, 0777);//改变文件模式,所有人都有执行权限、写权限、度权限

}

//得到唯一的文件名!防止因为文件名相同而产生覆盖

$uniName=md5(uniqid(microtime(true),true)).".$ext";//md5加密,uniqid产生唯一idmicrotime做前缀

//目标存放文件地址

$destination=$path."/".$uniName;

//当文件上传成功,存入临时文件夹,服务器端开始判断

if ($error===0) {

  if ($size>$maxsize) {

    exit("上传文件过大!");

  }

  if (!in_array($ext, $allowExt)) {

    exit("非法文件类型");

  }

  if (!is_uploaded_file($tmp_name)) {

    exit("上传方式有误,请使用post方式");

  }

  //判断是否为真实图片(防止伪装成图片的病毒一类的

  if (!getimagesize($tmp_name)) {//getimagesize真实返回数组,否则返回false

    exit("不是真正的图片类型");

  }

  //move_uploaded_file($tmp_name, "uploads/".$filename);

  if (@move_uploaded_file($tmp_name, $destination)) {//@错误抑制符,不让用户看到警告

    echo "文件".$filename."上传成功!";

  }else{

    echo "文件".$filename."上传失败!";

  }

}else{

  switch ($error){

    case 1:

      echo "超过了上传文件的最大值,请上传2M以下文件";

      break;

    case 2:

      echo "上传文件过多,请一次上传20个及以下文件!";

      break;

    case 3:

      echo "文件并未完全上传,请再次尝试!";

      break;

    case 4:

      echo "未选择上传文件!";

      break;

    case 7:

      echo "没有临时文件夹";

      break;

  }

}

1.3 封装上传函数

 

<?php

//定义一个uploadFile函数

function uploadFile($fileInfo,$path,$allowExt,$maxSize){

//取出$_FILES中的数据

$filename=$fileInfo["name"];

$tmp_name=$fileInfo["tmp_name"];

$size=$fileInfo["size"];

$error=$fileInfo["error"];

$type=$fileInfo["type"];

//取出文件路径中文件的类型的部分

$ext=pathinfo($filename,PATHINFO_EXTENSION);

//确定是否存在存放图片的文件夹,没有则新建一个

if (!file_exists($path)) {  //当目录不存在,就创建目录

  mkdir($path,0777,true);//创建目录

  chmod($path, 0777);//改变文件模式,所有人都有执行权限、写权限、度权限

}

//得到唯一的文件名!防止因为文件名相同而产生覆盖

$uniName=md5(uniqid(microtime(true),true)).'.'.$ext;

//目标存放文件地址

$destination=$path."/".$uniName;

//当文件上传成功,存入临时文件夹,服务器端开始判断

if ($error==0) {

  if ($size>$maxSize) {

    exit("上传文件过大!");

  }

  if (!in_array($ext, $allowExt)) {

    exit("非法文件类型");

  }

  if (!is_uploaded_file($tmp_name)) {

    exit("上传方式有误,请使用post方式");

  }

  //判断是否为真实图片(防止伪装成图片的病毒一类的

  if (!getimagesize($tmp_name)) {//getimagesize真实返回数组,否则返回false

    exit("不是真正的图片类型");

  }

  if (@move_uploaded_file($tmp_name, $destination)) {//@错误抑制符,不让用户看到警告

    echo "文件".$filename."上传成功!";

  }else{

    echo "文件".$filename."上传失败!";

  }

}else{

  switch ($error){

    case 1:

      echo "超过了上传文件的最大值,请上传2M以下文件";

      break;

    case 2:

      echo "上传文件过多,请一次上传20个及以下文件!";

      break;

    case 3:

      echo "文件并未完全上传,请再次尝试!";

      break;

    case 4:

      echo "未选择上传文件!";

      break;

    case 7:

      echo "没有临时文件夹";

      break;

  }

}

return $destination;

}

 

表单采取之前的 , 然后提交处理文件如下

<?php

header('content-type:text/html;charset=utf-8');

//初始化相关变量

$fileInfo=$_FILES["myFile"];

$maxSize=10485760;//10M,10*1024*1024

$allowExt=array('jpeg','jpg','png','tif');

$path="uploads";

//引入前面封装了的上传函数fun_upload.php

include_once 'fun_upload.php';

uploadFile($fileInfo, $path, $allowExt, $maxSize);

?>

 

这样我们就能够通过引用函数文件使用这个函数,这个函数会返回文件的路径

所以我们可以

$url=uploadFile($fileInfo, $path, $allowExt, $maxSize);

 

 

 

1.4 实现多文件上传

表单如下

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

<meta name="format-detection" content="telephone=no" />

<meta charset="utf-8" />

<title>多文件上传</title>

</head>

<body>

<form action="upload4.php" method="post" enctype="multipart/form-data">

请选择您要上传的文件:<input type="file" name="myFile1" /><br/>

请选择您要上传的文件:<input type="file" name="myFile2" /><br/>

请选择您要上传的文件:<input type="file" name="myFile3" /><br/>

请选择您要上传的文件:<input type="file" name="myFile4" /><br/>

<input type="submit" value="上传"/>

</form>

</body>

</html>

 

 

上传处理代码

<?php

//echo "<pre>";

//print_r($_FILES);

//echo "</pre>";

//exit;

header('content-type:text/html;charset=utf-8');

include_once 'fun_upload.php';

foreach ($_FILES as $fileInfo){

$file[]=uploadFile($fileInfo);

}

?>

$_FILES打印出来,打印出来看到是个二维数组,很简单,遍历去用就好了!

封装好的上传函数需要修改一下,给一些默认值

function uploadFile($fileInfo,$path="uploads",$allowExt=

array('jpeg','jpg','png','tif'),$maxSize=10485760){.....}

 

具体封装代码如下

<?php

function uploadFile( $fileInfo,$path="uploads",$allowExt=array('jpeg','jpg','png','tif'),$maxSize=10485760

){

$filename=$fileInfo["name"];

$tmp_name=$fileInfo["tmp_name"];

$size=$fileInfo["size"];

$error=$fileInfo["error"];

$type=$fileInfo["type"];

//服务器端设定限制

$ext=pathinfo($filename,PATHINFO_EXTENSION);

//目的信息

if (!file_exists($path)) {  

  mkdir($path,0777,true);

  chmod($path, 0777);

}

$uniName=md5(uniqid(microtime(true),true)).'.'.$ext;

$destination=$path."/".$uniName;

if ($error==0) {

  if ($size>$maxSize) {

    exit("上传文件过大!");

  }

  if (!in_array($ext, $allowExt)) {

    exit("非法文件类型");

  }

  if (!is_uploaded_file($tmp_name)) {

    exit("上传方式有误,请使用post方式");

  }

  //判断是否为真实图片(防止伪装成图片的病毒一类的

  if (!getimagesize($tmp_name)) {//getimagesize真实返回数组,否则返回false

    exit("不是真正的图片类型");

  }

  if (@move_uploaded_file($tmp_name, $destination)) {//@错误抑制符,不让用户看到警告

    echo "文件".$filename."上传成功!";

  }else{

    echo "文件".$filename."上传失败!";

  }

}else{

  switch ($error){

    case 1:

      echo "超过了上传文件的最大值,请上传2M以下文件";

      break;

    case 2:

      echo "上传文件过多,请一次上传20个及以下文件!";

      break;

    case 3:

      echo "文件并未完全上传,请再次尝试!";

      break;

    case 4:

      echo "未选择上传文件!";

      break;

    case 7:

      echo "没有临时文件夹";

      break;

  }

}

return $destination;

}

?>

 

 

1.5 文件的下载

<?php

//获取传递过来的路径信息

$filename=$_GET['filename'];

//判断是否有值,没有则不执行下面的php语句

if($filename){

header("Content-Disposition:attachment;filename=download_$filename");

//Content-disposition MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。

//格式:content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm 

//Content-Disposition为属性名

    //disposition-type是以什么方式下载,如attachment为以附件方式下载

     //disposition-parm为默认保存时的文件名

readfile($filename);

exit;

}

?>

<!DOCTYPE html>

<html>

<head>

<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">

 <meta name="format-detection" content="telephone=no" />

<title>文件下载</title>

<meta charset="utf-8" />

</head>

<body>

<a href="1.rar">下载1.rar</a>

<br />

<a href="1.jpg">下载1.jpg</a>

<br />

<a href="download.php?filename=1.jpg">通过程序下载1.jpg</a>

</body>

</html>

注:测试的时候,文件的同级目录下,必须存在1.rar1.jpg,也可以通过修改路径,

改变到自己的文件想要的文件夹下面

代码解

有三个下载连接

    一个对应图片(浏览器可以识别)

    一个对应压缩文件(浏览器不可以识别)

    最后一个还是图片,我们通过传递路径给当前页面,在页面顶端的php代码中实现当成一个附件打开或者保存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值