• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

PHP实现文件上传下载——心在忙而已

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

  这一周都没有写什么东西,是啊,一周时间都没有学习太多新的东西,除了开车。

妈蛋啊,天天中午去学车然后两周没有午觉的日子还是很崩溃的,加上之后工作压力带来的心忙,宝宝不开心啊。

不过,也是自己不是那么能吃苦吧。那天看到的那句话怎么说的来着,我痛恨自己,在简单和困难之前,选择了前者;在什么什么面前,balabala,不是很鸡汤,但有点触动,愿少点矫情和娇气。

PHP实现文件上传与下载——来自mooc网

一、上传原理与配置

1.1 原理

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

1.2 客户端配置

所需:表单页面(选择上传文件);

具体而言:发送方式为POST,添加enctype="multipart/form-data"属性,两者缺一不可(但是,优缺点并存,这里也限定了上传的方式和上传的文件之后的调用等方面,后面会说到)

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doAction.php" method="post" enctype="multipart/form-data">
请选择您要上传的文件:
<input type="file" name="myFile" /><br/>
<input type="submit" value="上传"/>
</form>
<?php

?>
</body>
</html>

先是表单页面(请自动忽略前端问题。。。),关键就是form的属性;另外就是input 中用到了type="file"这一点(体现到php的强大的拓展等等)。

然后是doAction

<?php
//$_FILES:文件上传变量
//print_r($_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;
    }
}

 

先把print_r($_FILES)这个信息看一下

Array
(
    [myFile] => Array
        (
            [name] => 梁博_简历.doc
            [type] => application/msword
            [tmp_name] => D:\wamp\tmp\php1D78.tmp
            [error] => 0
            [size] => 75776
        )

)

所以得到的是个二维数组,该怎么用,都是基本的东西(其实我喜欢降维再用);

基本是一眼就懂的东西,不罗嗦,关键有两个: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 客户端限制

<form action="doAction2.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>

 

这里用input的属性对上传文件的大小和类型进行了限制,但是个人感觉:一,html代码是“可见的”;二,常不起作用(没找到原因,但因为第一个我也想放弃它,知道就好。 

 2.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);
}
//$destination=$path."/".$filename;
//得到唯一的文件名!防止因为文件名相同而产生覆盖
$uniName=md5(uniqid(microtime(true),true)).$ext;//md5加密,uniqid产生唯一id,microtime做前缀


if ($error==0) {
    if ($size>$maxsize) {
        exit("上传文件过大!");
    }
    if (!in_array($ext, $allowExt)) {
        exit("非法文件类型");
    }
    if (!is_uploaded_file($tmp_name)) {
        exit("上传方式有误,请使用post方式");
    }
    if (@move_uploaded_file($tmp_name, $uniName)) {//@错误抑制符,不让用户看到警告
        echo "文件".$filename."上传成功!";
    }else{
        echo "文件".$filename."上传失败!";
    }
    //判断是否为真实图片(防止伪装成图片的病毒一类的
    if (!getimagesize($tmp_name)) {//getimagesize真实返回数组,否则返回false
        exit("不是真正的图片类型");
    }

}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;
    }
}

 

这里,具体实现都有注释,每一步其实都可以自己试试的,很有趣。

2.3 封装

函数

<?php
function uploadFile($fileInfo,$path,$allowExt,$maxSize){

$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";
include_once \'upFunc.php\';
uploadFile($fileInfo, $path, $allowExt, $maxSize);

 

三、多文件的上传实现

3.1 利用单文件封装

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doAction5.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
//print_r($_FILES);
header(\'content-type:text/html;charset=utf-8\');
include_once \'upFunc.php\';
foreach ($_FILES as $fileInfo){
    $file[]=uploadFile($fileInfo);
}

 

这里的思路,从print_r($_FILES)中去找,打印出来看到是个二维数组,很简单,遍历去用就好了! 

上面那个function的定义改一下,给定一些默认值

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

 

这样子,简单是简单,但遇到一些问题。

正常的上传4个图片是没问题,但要是中间激活了函数中的exit,就会立即停止,导致其他图片也无法上传。

3.2 升级版封装

旨在实现针对多个或单个文件上传的封装

首先这样子写个静态文件

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doAction5.php" method="post" enctype="multipart/form-data">
请选择您要上传的文件:<input type="file" name="myFile[]" /><br/>
请选择您要上传的文件:<input type="file" name="myFile[]" /><br/>
请选择您要上传的文件:<input type="file" name="myFile[]" /><br/>
请选择您要上传的文件:<input type="file" name="myFile[]" /><br/>
<input type="submit" value="上传"/>
</form>
</body>
</html>

 

打印一下$_FILES

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
                )

        )

)

 

可以得到一个三维数组。

复杂是复杂了,但复杂的有规律,各项数值都在一起了,很方便我们取值!!

所以先得到文件信息,变成单文件处理那种信息

function getFiles(){
    $i=0;
    foreach($_FILES as $file){
        if(is_string($file[\'name\'])){  //单文件判定
            $files[$i]=$file;
            $i++;
        }elseif(is_array($file[\'name\'])){
            foreach($file[\'name\'] as $key=>$val){  //我的天,这个$key用的diao
                $files[$i][\'name\']=$file[\'name\'][$key];
                $files[$i][\'type\']=$file[\'type\'][$key];
                $files[$i][\'tmp_name\']=$file[\'tmp_name\'][$key];
                $files[$i][\'error\']=$file[\'error\'][$key];
                $files[$i][\'size\']=$file[\'size\'][$key];
                $i++;
            }
        }
    }
    return $files;
    
}

 

然后之前的那种exit错误,就把exit改一下就好了,这里用res

function uploadFile($fileInfo,$path=\'./uploads\',$flag=true,$maxSize=1048576,$allowExt=array(\'jpeg\',\'jpg\',\'png\',\'gif\')){
    //$flag=true;
    //$allowExt=array(\'jpeg\',\'jpg\',\'gif\',\'png\');
    //$maxSize=1048576;//1M
    //判断错误号
    $res=array();
    if($fileInfo[\'error\']===UPLOAD_ERR_OK){
        //检测上传得到小
        if($fileInfo[\'size\']>$maxSize){
            $res[\'mes\']=$fileInfo[\'name\'].\'上传文件过大\';
        }
        $ext=getExt($fileInfo[\'name\']);
        //检测上传文件的文件类型
        if(!in_array($ext,$allowExt)){
            $res[\'mes\']=$fileInfo[\'name\'].\'非法文件类型\';
        }
        //检测是否是真实的图片类型
        if($flag){
            if(!getimagesize($fileInfo[\'tmp_name\'])){
                $res[\'mes\']=$fileInfo[\'name\'].\'不是真实图片类型\';
            }
        }
        //检测文件是否是通过HTTP POST上传上来的
        if(!is_uploaded_file($fileInfo[\'tmp_name\'])){
            $res[\'mes\']=$fileInfo[\'name\'].\'文件不是通过HTTP POST方式上传上来的\';
        }
        if($res) return $res;
        //$path=\'./uploads\';
        if(!file_exists($path)){
            mkdir($path,0777,true);
            chmod($path,0777);
        }
        $uniName=getUniName();
        $destination=$path.\'/\'.$uniName.\'.\'.$ext;
        if(!move_uploaded_file($fileInfo[\'tmp_name\'],$destination)){
            $res[\'mes\']=$fileInfo[\'name\'].\'文件移动失败\';
        }
        $res[\'mes\']=$fileInfo[\'name\'].\'上传成功\';
        $res[\'dest\']=$destination;
        return $res;
        
    }else{
        //匹配错误信息
        switch ($fileInfo [\'error\']) {
            case 1 :
                $res[\'mes\'] = \'上传文件超过了PHP配置文件中upload_max_filesize选项的值\';
                break;
            case 2 :
                $res[\'mes\'] = \'超过了表单MAX_FILE_SIZE限制的大小\';
                break;
            case 3 :
                $res[\'mes\'] = \'文件部分被上传\';
                break;
            case 4 :
                $res[\'mes\'] = \'没有选择上传文件\';
                break;
            case 6 :
                $res[\'mes\'] = \'没有找到临时目录\';
                break;
            case 7 :
            case 8 :
                $res[\'mes\'] = \'系统错误\';
                break;
        }
        return $res;
    }
}

 

里面封装了两个小的

function getExt($filename){
    return strtolower(pathinfo($filename,PATHINFO_EXTENSION));
}

/**
 * 产生唯一字符串
 * @return string
 */
function getUniName(){
    return md5(uniqid(microtime(true),true));
}

 

然后静态中,用multiple属性实现多个文件的输入;

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="doAction6.php" method="POST" enctype="multipart/form-data">
请选择您要上传的文件:<input type="file" name="myFile[]" multiple=\'multiple\' /><br/>
<input type="submit" value="上传"/>
</form>
                      

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
php扩展怎么开,php扩展哪里下载(转自百度)发布时间:2022-07-10
下一篇:
php工具、拓展下载地址发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap