PHP 文件上传

表单传值中 上传文件相交于上传数据比较特殊复杂  因为文件是二进制内容而不是普通字符流 

<html>
    <body> 
        <!--文件上传必须采用POST方式 -->
        <!--而且需要利用form的enctype属性 告诉HTTP协议使用到了文件上传 -->
        <!--如果不使用enctype属性 文件的上传是伪成功 $_FILES中没有任何数据 -->
        <!--第一个属性值 默认进行编码 选择第二个 multipart/form-data 不对数据进行编码 二进制不需要编码-->
        <form action='index.php' method="POST" enctype="multipart/form-data">
       文件输入:&nbsp;<input type="file" name='fileTest' value=''>
       <!--name的值是文件的名称 在$_FILES中作为第一维元素的值以及二维数组的索引 value可以为空 -->
       <input type="submit"  name='submit'>
        </form>
    </body>
    </html>

文件上传的第一步是把文件上传到操作系统 操作系统临时接收 接收数据的PHP文件中$_FILES数组有个元素内容为  ["tmp_name"]=> string(27) "C:\Windows\Temp\php6E3B.tmp" 此路径就是文件在操作系统中的默认文件 后面需要通过PHP代码对文件进行操作   否则是没有意义的 临时文件会自动消除 

<?php
//接收文件 通过系统预定义变量$_FIles 索引为表单中name属性的值
$files = $_FILES['fileTest'];
/*$files数组中一共有五个索引 分别是
*name => 上传文件的名称 例如 a.txt 
*type => 上传文件的种类 例如 image/png
*tmp_name => 系统接受的文件所在的绝对路径
* error => 错误代码 0代表没有错误
* size => 文件所在内存
*/
var_dump($files);
if($files['error']==0){
  move_uploaded_file($files['tmp_name'],'test/'.$files['name']);
  //move_uploaded_file的作用是把放在系统中的临时文件 转移到放置文件的文件夹 
  //临时文件后缀为.tmp 所以在转移的过程中需要更改名称 
  //两个参数  第一个参数临时文件路径 第二个参数为 更改后的文件
}
/*错误代码 1 文件过大
* 错误代码 2 文件过大
* 错误代码 3 文件只有部分上传
* 错误代码 4 用户没有选中要上传的文件
* 5是预留代码 6 7 都输服务器操作失败
*/

?>

PHP不应该信任任何外来数据  所以文件上传时一定要对其检验 可以封装一个函数 专门用于处理文件上传

<?php
/* 
*封装一个fileUpload方法 调用时需要传入的参数为别为
* 提出出来的文件数组 $file
* 想要转移到的目的路径 $path
* 告诉外部 文件的错误信心 $error 
* 文件的类型  $type =array()
*  文件的大小  系统默认2M $size=2000000;
*/
function fileUpload($file,$path,&$error,$type=array(),$size=2000000){
    //判断文件是否为文件 
    if(!isset($file['error'])){
        $error='上传目标不是有效文件';
        return false;
    }
    //isset()判断变量是否声明  如果不存在错误代码 返回false 同时说明 文件不合法
    //判断路径是否是有效路径
    if(!is_dir($path)){
        $error='路径不正确';
        return false;
    }
    //文件上传只要有问题 立即退出上传  所以error后面必接return语句
    //判断文件是否上传成功
    switch($file['error']){
        case 1 :
        case 2 :{
            $error='文件过大';
            return false;
        }
        case 3 : {
            $error ='文件只有部分上传';
            return false;
        }
        case 4 :{
            $error = '用户未选中目标文件';
            return false;
        }
        case 6:
        case 7:{
            $error ='服务器错误';
            return false;
        }
    }
    //判断文件类型是否符合
    if(!empty($type) && in_array($file['type'],$type)){
        $error ='类型错误';
            return false;
    }
    //默认为空 如果没有传入参数  第一个判断条件就会跳出不会报错
    // 如果传入参数 不为空 并且 文件的类型不在传入的类型时候 进入下面的语句 否则 跳出判断 
    //大小判定
    if($file['size']>$size){
        $error='文件过大 服务器所允许的最大值是'.($size/1000000).'M';
        return false;
    }
    //移动文件 即转存  
    //需要注意转存的文件名 名称重复等问题 
    //建立一个方法  getNewName 获取一个有规律的 随机性的名字
    $newFileName = getNewName($file['name']);
    move_uploaded_file($file['tmp_name'],$path. "\\" .$newFileName);

}
function getNewName($oldName){
    //以年月日时分秒开头
    $newName = date('YmdHis');
    //获得有 a-z A-Z组成的数组 
    $rand = array_merge(range('a','z'),range('A','Z'));
    //打乱数组
    shuffle($rand);
    //取打乱后的前4个接在年月日时分秒后面 
    for($a=0;$a<5;$a++){
        $newName .= $rand[$a];
    }
    //利用strstr方法 获取文件后缀名
    $str = strstr($oldName,'.');
   return  $newName .= $str;
}
?>

此时接收文件的PHP文件 只需要包含此文件 以及调用函数和传入参数即可 

<?php
//调用封装的函数 上传文件 一定要带once 
include_once "fileUpload.php";
//调用fileUIpload函数
$file = $_FILES['fileTest'];
$res =fileUpload($file,'F:\server\secondweb\test',$error);
//对上传数据进行判断
if(!$res){
    echo '文件上传成功';
}else{
    echo '文件上传失败 &nbsp;'.$error;
}
?>

多文件上传分为两种两种 第一种为多个单文件上传 其本质上还是单文件上传  比较容易理解  只需要重新调用一次上传函数即可

<html>
    <body> 
        
        <form action='index.php' method="POST" enctype="multipart/form-data">
        身份证正面照片:&nbsp;<input type="file" name='img1' value=''>
        <br/>
        身份证反面照片:&nbsp;<input type='file' name='img2' value=''>
         <input type="submit"  name='submit'>
        </form>
    </body>
    </html>
<?php
//调用封装的函数 上传文件 一定要带once 
include_once "fileUpload.php";
//调用fileUIpload函数
$file1 = $_FILES['img1'];
$file2 = $_FILES['img2'];
$res1 =fileUpload($file1,'F:\server\secondweb\test',$error);
$res2 =fileUpload($file2,'F:\server\secondweb\test',$error);
if(!$res1){
    echo '文件上传成功';
}else{
    echo '文件上传失败 &nbsp;'.$error;
}
if(!$res2){
    echo '文件上传成功';
}else{
    echo '文件上传失败 &nbsp;'.$error;
}
?>

还有一种多文件上传是同名多文件上传  PHP的$_FILES[ ] 是一个关联数组 正常情况下 键名对应的是input 表单的name属性的值 

  键会指定另一个据说上传文件信息的关联数组 这个数组自带5个键 (name type tmp_name error size )

在同名多文件上传时 如果name值是正常的名字的话 后面上传的信息会覆盖前面上传的信息 。 为了解决这个问题 name 的属性值需要做成数组的样式 例如 name = img[] 这样的话 后面上传的同名文件会自动加到数组 而不是覆盖前面的文件 同样 $_FILES的键名还是name的值

但是键所指定的数组的每一个元素 所指定的是仍然是一个数组(name=>{img1,img2,img3})(正常情况下是指定一个值 例如name=>'img'  ) 所以采用的方法就比较麻烦

<html>
    <body> 
        
        <form action='index2.php' method="POST" enctype="multipart/form-data">
        出游照片:&nbsp;<input type="file" name='img[]' value=''>
        <br/>
        &nbsp;<input type='file' name='img[]' value=''>
        &nbsp;<input type='file' name='img[]' value=''>
         <input type="submit"  name='submit' value="upload">
        </form>
    </body>
    </html>
<?php
include_once "fileUpload.php";
//提取到上传的文件 
$file = $_FILES['img'];
//此时file 依旧是个二维数组 先判断第二维数组的长度
$len = count($file['name']);
//从二维数组$files提取出每个文件的信息 然后进行上传
for($a=0;$a<$len;$a++){
    $img=array(
        'name'=> $file['name'][$a],
        'type'=>$file['type'][$a],
        'tmp_name' =>$file['tmp_name'][$a],
        'error'=>$file['error'][$a],
        'size'=>$file['size'][$a]
    );
    //提取出每个文件所需要的5个信息之后 调用上传函数
    $res = fileUpload($img,'./dir',$error);
    if(!$res){
        echo  '文件上传成功 文件名为'.$img['name'];
    }else{
        echo '文件上传失败';
    }
}
?>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值