PHP文件上传

Posted 飞鱼0725

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP文件上传相关的知识,希望对你有一定的参考价值。

文件上传需要注意php.ini文件,php.ini的文件太多,找不到的时候你可以使用CTRL+f搜索相关配置项。

配置项功能说明
file_uploads on为 开启文件上传功能,off为关闭
post_max_size 系统允许的POST传参的最大值
upload_max_filesize 系统允许的上传文件的最大值
memory_limit 内存使用限制

建议尺寸: file_size(文件大小) < upload_max_filesize < post_max_size < memory_limit

文件上传的步骤:

一、判断是否有错误码

错误码说明
0 无误,可以继续进行文件上传的后续操作。
1 超出上传文件的最大限制,upload_max_filesize = 2M php.ini中设置,一般默认为2M。可根据项目中的实际需要来修改
2 超出了指定的文件大小,根据项目的业务需求指定上传文件的大小限制
3 只有部分文件被上传
4 文件没有被上传
6 找不到临时文件夹,可能目录不存在或没权限
7 文件写入失败,可能磁盘满了或没有权限

二、自定义判断是否超出文件大小范围

在开发上传功能时。我们作为开发人员,除了php.ini中规定的上传的最大值外。

我们通常还会设定一个值,是业务规定的上传大小限制。

例如:
新浪微博或者QQ空间只准单张头像图片2M。而在上传图册的时候又可以超过2M来上传。

所以说,它的系统是支持更大文件上传的。

此处的判断文件大小,我们用于限制实际业务中我们想要规定的上传的文件大小。

三、判断后缀名和mime类型是否符合

在网络世界里面也有坏人。他们会把图片插入病毒,在附件中上传病毒,他们会在网页中插入病毒或者黄色图片。

我们需要对于上传的文件后缀和mime类型都要进行判断才可以。

MIME(Multipurpose Internet Mail Extensions)是多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

在判断后缀和MIME类型的时候,我们会用到PHP的一个函数in_array(),该函数传入两个参数。
第一个参数是要判断的值;
第二个参数是范围数组。

我们用这个函数来判断文件的后缀名和mime类型是否在允许的范围内。

四、生成文件名

我们的文件上传成功了,不会让它保存原名。
因为,有些人在原名中有敏感关键词会违反我国的相关法律和法规。

我们可以采用date()、mt_rand()或者unique()生成随机的文件名。

五、判断是否是上传文件

文件上传成功时,系统会将上传的临时文件上传到系统的临时目录中。产生一个临时文件。

同时会产生临时文件名。我们需要做的事情是将临时文件移动到系统的指定目录中。

而移动前不能瞎移动,或者移动错了都是不科学的。移动前我们需要使用相关函数判断上传的文件是不是临时文件。

is_uploaded_file()传入一个参数($_FILES中的缓存文件名),判断传入的名称是不是上传文件。

六、移动临时文件到指定位置

临时文件是真实的临时文件,我们需要将其移动到我们的网站目录下面了。

让我们网站目录的数据,其他人可以访问到。

我们使用:move_uploaded_file()。
这个函数是将上传文件移动到指定位置,并命名。
传入两个参数:
第一个参数是指定移动的上传文件;
第二个参数是指定的文件夹和名称拼接的字符串。

注意事项:

    1.form 表单中的参数method 必须为post。若为get是无法进行文件上传的

    2.enctype须为multipart/form-data

七、PHP按照数组和步骤完成文件上传

PHP为文件类数据准备了一个专用的系统函数$_FILES,上传文件的所有相关数据,都保存在这个系统函数中。

在PHP文件中,我们打印 $_FILES ,来观察这个数组的结构:

array (size=1)
    file => 
       array (size=5)
       //文件名
      name => string psu.jpg (length=7) 
      //文件的mime类型
      type => string image/jpeg (length=10)                    
      //缓存文件,上传的图片即保存在这里
      tmp_name => string E:wamp	mpphpC32A.tmp (length=23)
      //错误码,详见上面错误码介绍
      error => int 0                                             
      //上传的文件大小
      size => int 225824

得到了上面的数组结构。

我们就可以开始文件的处理过程了。

第一步,判断错误码:

<?php
if($_FILES[file][error] > 0){
   switch ($_FILES[file][error]) {    //错误码不为0,即文件上传过程中出现了错误
       case 1:
           echo 文件过大;
           break;
       case 2:
           echo 文件超出指定大小;
           break;
       case 3:
           echo 只有部分文件被上传;
           break;
       case 4:
           echo 文件没有被上传;
           break;
       case 6:
           echo 找不到指定文件夹;
           break;
       case 7:
           echo 文件写入失败;
           break;
       default:
           echo "上传出错<br/>";
   }
}else{
   //错误码为0,即上传成功,可以进行后续处理,处理流程见下文
}
?>

第二步:判断文件是否超出大小

<?php
//判断错误
if ($_FILES[file][error] > 0) {
    //有错误可停止执行
} else {
    //当前上传文件无误,运行本段代码
    //判断文件是否超出了指定的大小
    //单位为byte
    $MAX_FILE_SIZE = 100000;
    if ($_FILES[file][size] > $MAX_FILE_SIZE) {
        //判断,如果上传的文件,大小超出了我们给的限制范围,退上传并产生错误提示
        exit("文件超出指定大小");
    }
}
?>

第三步,判断文件的mime类型是否正确。

<?php
/*判断后缀名和MIME类型是否符合指定需求
例如:
当前项目指定上传后缀为.jpg或.gif的图片,则$allowSuffix = array(‘jpg‘,‘gif‘);
*/
//定义允许的后缀名数组
$myImg = explode(., $_FILES[file][name]);
/*
explode() 将一个字符串用指定的字符切割,并返回一个数组,这里我们将文件名用‘.‘‘切割,结果存在$myImg中,文件的后缀名即为数组的最后一个值
*/
$myImgSuffix = array_pop($myImg);
/*
根据上传文件名获取文件的后缀名
使用in_array()函数,判断上传文件是否符合要求
当文件后缀名不在我们允许的范围内时退出上传并返回错误信息
*/
if(!in_array($myImgSuffix, $allowSuffix)){
    exit("文件后缀名不符");
}
/*
mime类型和文件后缀名的对应关系,我们可以通过很多途径查询到,为了避免用户自主修改文件后缀名造成文件无法使用。
mime类型也必须做出限制检查mime类型,是为了防止上传者直接修改文件后缀名
导致文件不可用或上传的文件不符合要求。
*/
//数组内容为允许上传的mime类型
$allowMime = array(
    "image/jpg",
    "image/jpeg",
    "image/pjpeg",
    "image/gif"
);
if(!in_array($_FILES[file][type], $allowMime)){                      //判断上传文件的mime类型是否在允许的范围内
    exit(文件格式不正确,请检查);
    //如果不在允许范围内,退出上传并返回错误信息
}
?>

第四步,生成指定的路径和文件名

第五步,判断是否是上传文件

is_uploaded_file()

第六步,移动文件到指定位置

使用move_uploaded_file()函数,将文件移动到指定的位置,并命名。

<?php
/*
使用move_uploaded_file()移动上传文件至指定位置,第一个参数为上传文件,第二个参数为我们在前面指定的上传路径和名称。
*/
if(move_uploaded_file($_FILEs[file][tmp_name], $path.$name)){
           //提示文件上传成功
           echo "上传成功";                                
       }else{
/*
文件移动失败,检查磁盘是否有足够的空间,或者linux类系统中文件夹是否有足够的操作权限
*/
           echo 上传失败;                                                
       }
   }else{
       echo 不是上传文件;
   }

}
?>

八、文件上传进度处理

PHP在5.4之前,总是需要安装额外的扩展才能监控到文件上传进度。而从5.4开始,引入session.upload_progress的新特性,我们只需要在php.ini中开启配置,即可通过session监控文件上传进度。在php.ini中。

注意:本章学习需要有session基础和javascript和ajax基础。

我们需要配置,注意查看和修改php.ini文件:

配置项说明
session.upload_progress.enabled 是否启用上传进度报告(默认开启) 1为开启,0为关闭
session.upload_progress.cleanup 是否在上传完成后及时删除进度数据(默认开启, 推荐开启)
session.upload_progress.prefix[=upload_progress_] 进度数据将存储在_SESSION[session.upload_progress.prefix . _POST[session.upload_progress.name]]
session.upload_progress.name[=PHP_SESSION_UPLOAD_PROGRESS] 如果_POST[session.upload_progress.name]没有被设置, 则不会报告进度.
session.upload_progress.freq[=1%] 更新进度的频率(已经处理的字节数), 也支持百分比表示’%’.
session.upload_progress.min_freq[=1.0] 更新进度的时间间隔(秒级)

 









以上是关于PHP文件上传的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 PHP,预期文件结尾,我错在哪里?

android的自带的httpClient 怎么上传文件

PHP常用代码片段

Alamofire 文件上传出现错误“JSON 文本未以数组或对象开头,并且允许未设置片段的选项”

PHP文件上传代码用法

php文件上传漏洞代码只允许上传图片