PHP实现文件上传下载实例详细讲解-php教程

资源魔 26 0
1、上传原理与设置装备摆设

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

<?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——最年夜复线程的自力内存应用量

总之都是无关资本的设置装备摆设。

--谬误号

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、上传相干限度

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','gif');//容许上传的文件类型(拓展名
$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、多文件的上传完成

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>
</body>
</html>

doAction6.php

<?php 
//print_r($_FILES);
header("content-type:text/html;charset=utf-8");
require_once 'upFunc2.php';
require_once 'co妹妹on.func.php';
$files=getFiles();
// print_r($files);
foreach($files as $fileInfo){
    $res=uploadFile($fileInfo);
    echo $res['mes'],'<br/>';
    $uploadFiles[]=@$res['dest'];
}
$uploadFiles=array_values(array_filter($uploadFiles));
//print_r($uploadFiles);

4、面向工具的文件上传

<?php 
class upload{
    protected $fileName;
    protected $maxSize;
    protected $allowMime;
    protected $allowExt;
    protected $uploadPath;
    protected $imgFlag;
    protected $fileInfo;
    protected $error;
    protected $ext;
    /**
     * @param string $fileName
     * @param string $uploadPath
     * @param string $imgFlag
     * @param number $maxSize
     * @param array $allowExt
     * @param array $allowMime
     */
    public function __construct($fileName='myFile',$uploadPath='./uploads',$imgFlag=true,$maxSize=5242880,$allowExt=array('jpeg','jpg','png','gif'),$allowMime=array('image/jpeg','image/png','image/gif')){
        $this->fileName=$fileName;
        $this->maxSize=$maxSize;
        $this->allowMime=$allowMime;
        $this->allowExt=$allowExt;
        $this->uploadPath=$uploadPath;
        $this->imgFlag=$imgFlag;
        $this->fileInfo=$_FILES[$this->fileName];
    }
    /**
     * 检测上传文件能否犯错
     * @return boolean
     */
    protected function checkError(){
        if(!is_null($this->fileInfo)){
            if($this->fileInfo['error']>0){
                switch($this->fileInfo['error']){
                    case 1:
                        $this->error='超越了PHP设置装备摆设文件中upload_max_filesize选项的值';
                        break;
                    case 2:
                        $this->error='超越了表单中MAX_FILE_SIZE设置的值';
                        break;
                    case 3:
                        $this->error='文件局部被上传';
                        break;
                    case 4:
                        $this->error='不抉择上传文件';
                        break;
                    case 6:
                        $this->error='不找到暂时目次';
                        break;
                    case 7:
                        $this->error='文件不成写';
                        break;
                    case 8:
                        $this->error='因为PHP的扩大顺序中缀文件上传';
                        break;
                        
                }
                return false;
            }else{
                return true;
            }
        }else{
            $this->error='文件上传犯错';
            return false;
        }
    }
    /**
     * 检测上传文件的巨细
     * @return boolean
     */
    protected function checkSize(){
        if($this->fileInfo['size']>$this->maxSize){
            $this->error='上传文件过年夜';
            return false;
        }
        return true;
    }
    /**
     * 检测扩大名
     * @return boolean
     */
    protected function checkExt(){
        $this->ext=strtolower(pathinfo($this->fileInfo['name'],PATHINFO_EXTENSION));
        if(!in_array($this->ext,$this->allowExt)){
            $this->error='没有容许的扩大名';
            return false;
        }
        return true;
    }
    /**
     * 检测文件的类型
     * @return boolean
     */
    protected function checkMime(){
        if(!in_array($this->fileInfo['type'],$this->allowMime)){
            $this->error='没有容许的文件类型';
            return false;
        }
        return true;
    }
    /**
     * 检测能否是实在图片
     * @return boolean
     */
    protected function checkTrueImg(){
        if($this->imgFlag){
            if(!@getimagesize($this->fileInfo['tmp_name'])){
                $this->error='没有是实在图片';
                return false;
            }
            return true;
        }
    }
    /**
     * 检测能否经过HTTP POST形式上传下去的
     * @return boolean
     */
    protected function checkHTTPPost(){
        if(!is_uploaded_file($this->fileInfo['tmp_name'])){
            $this->error='文件没有是经过HTTP POST形式上传下去的';
            return false;
        }
        return true;
    }
    /**
     *显示谬误 
     */
    protected function showError(){
        exit('<span style="color:red">'.$this->error.'</span>');
    }
    /**
     * 检测目次没有存正在则创立
     */
    protected function checkUploadPath(){
        if(!file_exists($this->uploadPath)){
            mkdir($this->uploadPath,0777,true);
        }
    }
    /**
     * 孕育发生惟一字符串
     * @return string
     */
    protected function getUniName(){
        return md5(uniqid(microtime(true),true));
    }
    /**
     * 上传文件
     * @return string
     */
    public function uploadFile(){
        if($this->checkError()&&$this->checkSize()&&$this->checkExt()&&$this->checkMime()&&$this->checkTrueImg()&&$this->checkHTTPPost()){
            $this->checkUploadPath();
            $this->uniName=$this->getUniName();
            $this->destination=$this->uploadPath.'/'.$this->uniName.'.'.$this->ext;
            if(@move_uploaded_file($this->fileInfo['tmp_name'], $this->destination)){
                return  $this->destination;
            }else{
                $this->error='文件挪动失败';
                $this->showError();
            }
        }else{
            $this->showError();
        }
    }
}
<?php 
header('content-type:text/html;charset=utf-8');
require_once 'upload.class.php';
$upload=new upload('myFile1','imooc');
$dest=$upload->uploadFile();
echo $dest;

5、下载

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Insert title here</title>
</head>
<body>
<a href="1.rar">下载1.rar</a>
<br />
<a href="1.jpg">下载1.jpg</a>
<br />
<a href="doDownload.php?filename=1.jpg">经过顺序下载1.jpg</a>
<br />
<a href="doDownload.php?filename=../upload/nv.jpg">下载nv.jpg</a>
<?php

?>
</body>
</html>
<?php 
$filename=$_GET['filename'];
header('content-disposition:attachment;
filename='.basename($filename));
header('content-length:'.filesize($filename));
readfile($filename);

总结:

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

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

二维数组的降维解决;

$_FILES变量

move_upload_file();copy();

tmp_name暂时文件;

拓展名的提取;

实在图片的验证;

惟一文件名的天生;

函数封装和挪用;

行使单个文件函数完成多文件上传;

小性能的封装;

多文件的遍历;

面向工具的开发进程;

下载;

以上就是全副的解说,心愿能够协助到各人,有谬误之处请指出。

更多相干成绩请拜访PHP中文网:PHP视频教程

以上就是PHP完成文件上传下载实例具体解说的具体内容,更多请存眷资源魔其它相干文章!

标签: 文件上传 php开发教程 php开发资料 php开发自学

抱歉,评论功能暂时关闭!