自学php学习笔记--php的文件上传与下载函数知识

php 图片上传 php 1200      收藏
本文为php学习笔记,主要讲述php文件上传原理,php文件上传方法,php文件下载,php文件下载方法等。较详细的介绍了php上传和下载的相关知识。

自学php博客


使用表单来上传文件

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

<label for=“file”>文件名:</label>     

<input type="file" name=“photo" />      

<input type=“submit” name=“sub” value=“提交" /> 

</form>

上传文件的过程其实就是一个文件的复制过程,在客户端Web页面用户通过HTTP协议将文件复制(上传)到服务端(服务器上)的临时文件夹,然后再使用PHP的系统函数,将临时文件移动到指定的目录中,从而完成整个上传过程。

自学php博客

文件上传简介 

案例:

test.php

<?php


?>

<meta charset=utf-8 />

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

<input type="file" name=“photo" />   

<br />   

<input type=“submit” name=“sub” value=“提交" />

</form>


upload.php

<?php

$max_size=700*1024;

if($_FILES['photo']['size']>$max_size){

    echo "文件太大";

    exit;

}

if($_FILES['photo']['error']==0){

//文件已经被上传到服务器临时目录下

$rs=move_uploaded_file($_FILES['photo']['tmp_name'],'./up/'.$_FILES['photo']['name']);

}else{

echo '文件上传失败';

}

?>


在服务器端,使用 PHP 的全局数组$_FILES(肯定是一个二维数组),来获取用户上传的文件的信息 (文件上传的信息统一存放在二维数组里$_FILES)


$_FILES 是一个二维数组,元素的索引值为input框的name属性的值,索引对应的内容为一个一维数组,此数组固定有5个元素,记录了被上传文件的详细信息 

$_FILES['photo']['name']:         上传文件在客户端原名称 

$_FILES['photo']['type']:         文件类型 

$_FILES['photo']['size']:         被上传的大小,单位:byte 

$_FILES['photo']['tmp_name']:     服务器端临时文件名(文件上传会短暂存在临时文件夹里,脚本结束就会巴临时文件删除) 

$_FILES['photo']['error']:        上传时产生的错误信息代码

如果没有设置enctype的话,$_FILES接收不到数据

错误代码取值范围

错误值2的,MAX_FILE_SIZE,现在已经没有使用价值,因为谷歌浏览器的审查元素,可以直接对其更改,避开了系统设置的值,所以这个属性已经没有意义了。

移动临时文件 

临时的复制文件会在脚本结束时消失。要保存被上传的文件,需要把他拷贝到另外一个位置 

bool move_uploaded_file(string $tmp_file, string $path) 

$tmp_file:临时文件的名字,$_FILES[‘photo’][‘tmp_name’] 

$path:移动文件到这个位置 

PHP代码

<?php 

if ($_FILES["photo"]["error"] > 0) {     

echo "错误代码: " . $_FILES["photo"]["error"] . "<br />"; 

} else{     

$path = ‘./upload/’.$_FILES[‘photo’][‘name’(名字可以自己设置,而且这个地方必须设置名字)];

//需要注意的是,上传之后的文件名,如果再次上传一个同名的文件,会把之前的覆盖掉 

move_uploaded_file($_FILES[‘photo’][‘tmp_name’], $path); 

?> 

解决文件名覆盖的办法:

1、每天创建子文件夹,命名为每天的日期,每天的数据存在每天的文件夹里面。

2、保证文件名唯一,使用uniqid()函数生成一个唯一数。//依据时间戳返回值是一个唯一的字符串

<?php

echo uniqid().<br />;

sleep(1);//脚本执行很快,不加这句话,前后两个是生成的一样的,这个函数可以让程序在这间隔一秒

也可以用uniqid('a'),在生成的字串前面加上前缀,以便于区分

echo uniqid().<br />;

?>

我们可以通过修改PHP配置文件(php.ini),来对上传功能进行设置 

配置名

默认值

说明

file_uploads

ON

服务器是否支持上传(ON / OFF)

memory_limit

128M

服务器处理单次请求,能分配出的最大内存

upload_max_filesize

64M

单个上传文件的最大值

post_max_size

3M

单次POST请求允许提交的最大数据量

upload_tmp_dir

wamp/tmp

临时文件的存储目录,如果为空,则使用系统默认值


允许用户上传文件是一个巨大的安全风险,如果你的web应用用不到上传功能,请配置你的php.ini,关闭此功能 

通常要对上传的文件进行一定的限制 

  • 文件类型限制 

  • 文件大小限制 

限制文件的类型 

<?php  

if($_FILES[‘files’][‘type’] == ‘image/jpeg’ || $_FILES[‘files’][‘type’] == ‘image/pjpeg’ or $_FILES[‘files’][‘type’] == ‘image/gif’ ){      

(上传操作) 

} else {      

echo ‘类型不正确!';  

}  

?> 

(if($_FILES[‘files’][‘type’] == ‘image/jpeg’ || $_FILES[‘files’][‘type’] == ‘image/pjpeg’ or $_FILES[‘files’][‘type’] == ‘image/gif’)如果有很多种类型,每个都这样写的话,特别麻烦,所以考虑优化,使用in_array函数进行设置。$type=array('image/jpg','inmage/pjpeg','image/png',....);然后if(in_array($_FILES['photo']['type'],$type)){};注意:if属于项目逻辑代码,以后项目在修改的时候,对于这种逻辑的内容尽量不要修改,就是类似这种提出到数组的思想,可以提高程序的灵活性。

而且对于,一些文件类型相同,但是后缀名不一样的话,需要更精确的判断,需要对文件后缀名进行限制。

$txt=substr($_FILES['photo']['name'],syrrpos($_FILES['photo']['name'],'.'))//取得文件后缀名

限制文件的大小 

<?php  

$max_size = 2*1024*1024;    //2MB 设定大小时要转化成B(字节)。

if  ($_FILES[“photo”][“size”] < $max_size)  {      

(上传操作) 

} else {      

echo ‘请上传小于2MB的文件';  

}  

?> 

多文件上传 

多文件上传和单独文件上传的方式相同,只需要在HTML中增加多个“file”类型的input标签,并制定不同的“name”值即可

多文件上传案例:

demo.php

<?php


?>

<meta charset=utf-8 />

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

<input type="file" name=“photo" />

<input type="file" name=“logo" />

<input type="file" name=“txt" />   

<br />   

<input type=“submit” name=“sub” value=“提交" />

</form>


upload.php

<?php

$max_size=700*1024;//这一部分可以放在配置文件中


//$config=include(./config/config.php);

//if($row['size']>$config['max_size']){

// echo '文件太大';exit;

//}

if($_FILES['photo']['size']>$max_size){

    echo "文件太大";

    exit;

}

foreach($_FILES as $key => $row){

    if($row['error']!=0){

    continue;

    }

    $tmp=uniqid(key);

    //或者rand生成随机数,rand(int $i,int $k),生成$i--$k的随机数

    // $rs=rand(10,99);

    //$tmp=uniqid($rs);

    //保证文件名长度相等$tmp=md5($tmp);

    $new_path='./up'.date('Ymd').$tmp;

    if(!file_exists($new_path)){

        mkdir($new_path,0777);

    }

    $hz=strrchr($row['name'],'.');//这个函数取得‘.’开始知道字符串结束的部分,并返回这段字符。

    $new_path.=$hz;

    move_uploaded_file($row['tmp_name'],$new_path);

}

}

?>

配置文件:

config.php

<?php

return array(

'max_size'=>900*1024,

'type'=>array(

    'image/jpg',

    'image/png'

    )

)

?>

多文件上传的补充知识:

如果不确定客户要上传多少个文件,怎么让客户自由选择上传多少文件?

<meta charset=utf-8 />

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

<input type="file" name=“photo" />

<input type="file" name=“logo" />

<input type="file" name=“txt" />   

<br />   

<input type=“submit” name=“sub” value=“提交" />

</form>

<?php

    if(empty($_GET['NUM'])){

        $i=0;

    }ele{

        $i=$_GET['num'];

    }

    if($_GET['act']==add){

    }

    <a href='./up3.php?act=add&num=<?php echo $i;?>'>新增一个上传框</a>

?>

<?php

    $num=$_GET['num'];

    for($i=0;$i<$num;$i++){

        echo '<input type="file" name="name'.$i.'"';

    }

?>


文件下载

文件下载有2种方式: 

url模式: <a href=“http://www.itaotmall.com/a.zip”>下载</a> 

href中的地址不可以写c:/a/...这种本地的地址,href对应的必须是在线的一个页面,一个合法的url,也可以是一个相对路径。

文件读取模式: 首先需要告知浏览器,将要进行下载文件的处理 

然后将文件内容读取出来,输出到浏览器端

<?php 

$file = fopen("upload/aaa.jpg","r"); 

header("Content-type:application/octet-stream");     //数据以二进制方式传输 

header("Accept-Ranges:bytes");                 //按照字节格式返回 

header("Accept-Length:".filesize("upload/aaa.jpg")); //返回文件的大小 

// attachment:作为附件下载,filename:默认的文件名字 

header("Content-Disposition: attachment; filename=aaa.jpg"); 

//防止服务器瞬时压力增大,分段读取 

while(!feof($file)){     

echo fread($file,1024); 

} fclose($file); 

?> 


a标签的安全性不好,会把文件的路径展示出来,容易让别人把网站内容采集走,所以建议是采用文件读取模式下载。

download.php

<?php 

if(!empty($_GET['name'])){

    $file_name=$_GET['name'];

}

$path='./up/2016/'.$file_name;

$download_name=$file_name;

header("Content-type:application/octet-stream");     //数据以二进制方式传输 

header("Accept-Ranges:bytes");                 //按照字节格式返回 

header("Accept-Length:".filesize("upload/$path")); //返回文件的大小 

// attachment:作为附件下载,filename:默认的文件名字 

header("Content-Disposition: attachment; filename=$download_name(这个名字可以自定义)"); 

$file = fopen("upload/$download_name","r"); 

//防止服务器瞬时压力增大,分段读取 

while(!feof($file)){     

echo fread($file,1024); 

fclose($file); 

?>

 

下面是图片的页面

<?php


?>

<a href=“./download.php?name=js.rar”>下载</a> 

<a href=“./download.php?name=jas.rar”>下载</a>