PHP 文件上传的原理及案例分析

Wesley13
• 阅读 730

原理

将客户端文件上传至服务器端,在服务器端临时存储,再将服务器端临时存储的文件移至指定位置


实现文件上传需要的知识点:

  • 前端页面

1.form表单必须是用post发送方式,因为get会将参数带到url中,而上传的文件转换后字符会很长,而且也是为了安全性

2.form表单需要使用enctype=“multipart/form-data”属性,form表单默认的enctype属性值是application/x-www-form-urlencoded,该属性在发送前编码所有字符,而multipart/form-data属性

不会编码字符,在使用包含文件上传控件的表单时,必须使用该值。

3.input 中用到了type="file"属性

  • 后端php页面

1.$_FILES:通过 HTTP POST 方式上传到当前脚本的项目的数组,也就是实现文件上传的数组,它的本质是一个数组,在PHP文档中我们可以看到它有以下几个内容,假设文件上传字段的名称为 userfile(此名称可随意命名的)

$_FILES['userfile']['name'] :客户端机器文件的原名称,也就是即将上传的文件的名称

$_FILES['userfile']['type']:文件的 MIME 类型,如果浏览器提供此信息的话。一个例子是“image/gif”。不过此 MIME 类型在 PHP 端并不检查,因此不要想当然认为有这个值。

$_FILES['userfile']['size']:已上传文件的大小,单位为字节。在限定用户上传文件的大小时将用到。

$_FILES['userfile']['tmp_name']:文件被上传后在服务端储存的临时文件名。

$_FILES['userfile']['error']:和该文件上传相关的错误代码。

文件被上传后,默认地会被储存到服务端的默认临时目录中。

2.move_uploaded_file( 临时文件名 , 指定目录文件名) :此函数将上传的文件移动到新位置,也就是实现文件上传的基本函数,检查并确保由 filename 指定的文件是合法的上传文件,如果文件合法,则将其移动为指定的文件。

3.in_array(‘value’,array,type) :‘value’是要搜索的值,array是要搜索的数组,type是否是要求全等,此参数可选,如果为true,要求搜索的结果不仅是值相等,类型也要相等

4.file_exists(path)检查文件或目录是否存在

5.pathinfo(path,options):以数组的形式分解文件路径的信息,其中options有以下几个参数: . PATHINFO_DIRNAME - 只返回 dirname . PATHINFO_BASENAME - 只返回 basename . PATHINFO_EXTENSION - 只返回 extension


实现上传流程

1.form表单提交 2.使用$_FILE获取上传内容的信息 3.校验上传内容是否符合规定的文件类型以及大小 4.通过检验后使用move_uploaded_file函数,将临时存储文件移至指定位置


案例代码

前端,请忽略样式

<form action="up.php" method="post" name="upform" enctype="multipart/form-data">
      <input type="hidden" name="MAX_FILE_SIEZ" value="200000" /> <!-设置上传最大文件为2M->
     上传文件<input type="file" name="upfile" />
      <input type="submit" name="submit" value="上传" />
</form>

php代码

if( isset($_POST['submit']) ){
    var_dump($_FILES['upfile']);
    //将获得的数据存储在变量中
    $name = $_FILES['upfile']['name'];
    $type = $_FILES['upfile']['type'];
    $tmp_name = $_FILES['upfile']['tmp_name'];
    $error = $_FILES['upfile']['error'];
    $size = $_FILES['upfile']['size'];

    //提取文件的扩展名,为今后类型判断做准备
    $ext = pathinfo($name,PATHINFO_EXTENSION); 
    $type_array = array('jpeg','pjeg','gif','png');
    //echo $ext;

    //设置上传文件后服务器存储位置,如果创建未成功,则说明没有权限
     $path = "uploads";
    if ( !file_exists( $path) ) {
            mkdir($path,0777,true);
            chmod($path,0777);
        }
    //当#error为0时进行大小,格式的判断
    if( $error == 0 ) {
            if ( $size > 200000) {
                exit('上传文件太大!');
            }
            if ( !in_array($ext,$type_array) ) {
                exit('非法文件类型');
            }
            if ( move_uploaded_file($tmp_name,'uploads/'.$name)) {
                echo '文件上传成功!';
            }else{
                echo '文件上传失败';
            }
    } else {
        switch ($error) {
            case 1 :
             echo "超过上传文件最大值,请上传2M以内的文件";
             break;
            case 2:
                echo "文件过多,只能上传一个";
                break;
            case 3:
                echo "文件没有完全上传,请重试";
                break;
             case 4:
                echo "未选择上传文件";
                break;
            case 7:
                echo "没有临时文件夹";
                break;
        }
    }
}

在实践时遇到了各种各样的问题,会在另一篇文章中单独说明

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
2年前
java中使用restful web service来传输文件
【1】上传大文件:前端页面:1)同步上传:<html<body<formaction"http://localhost:8081/webProject/api/file/uploadFile"method"post"enctype"multipart/form
Stella981 Stella981
2年前
Play 2.0 用户指南 - 文件上传 -- 针对Scala开发者
   处理文件上传   在form中指定multipart/formdata属性上传文件   上传文件的标准方式是指定form的一个特殊属性multipart/formdata,可以让你混合表单数据和表单文件附件。   开始编写HTML表单:@form(actionrou
Stella981 Stella981
2年前
Apache禁止解析PHP、禁止指定user_agent、php配置文件
Apache禁止解析PHP某个目录禁止解析PHP,是很有用的。特别是能够上传文件的目录。做网站安全的时候,这用的很多,比如某个目录可以上传文件,为了防止上传的文件有木马,所以我们禁止这个目录下面的访问解析PHP禁止解析PHP修改虚拟主机配置文件vim/usr/local/apache2/conf/ext
Wesley13 Wesley13
2年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Wesley13 Wesley13
2年前
PHP实现图片(文件)上传
这几天整理做过的php项目,感觉这个经常会用到,传上来共享一下咯首先,前端界面1、表单的首行需要加上enctype"multipart/formdata",需要上传的图片必须设置type"file"表示选择文件<formid"img_form"method"post"class"formhorizontal"r
Wesley13 Wesley13
2年前
PHP创建多级树型结构
<!lang:php<?php$areaarray(array('id'1,'pid'0,'name''中国'),array('id'5,'pid'0,'name''美国'),array('id'2,'pid'1,'name''吉林'),array('id'4,'pid'2,'n
Stella981 Stella981
2年前
Django
一:form表单标签的文件上传1:浏览器:html文件<h4form文件上传</h4<formaction"/file_put/"method"post"enctype"multipart/formdata"{%csrf_token
Wesley13 Wesley13
2年前
Java多线程导致的的一个事物性问题
业务场景我们现在有一个类似于文件上传的功能,各个子站点接受业务,业务上传文件,各个子站点的文件需要提交到总站点保存,文件是按批次提交到总站点的,也就是说,一个批次下面约有几百个文件。      考虑到白天提交这么多文件会影响到子站点其他系统带宽,我们将分站点的文件提交到总站点这个操作过程独立出来,放到晚上来做,具体时间是晚上7:00到早上7:00。
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这