PHP的学习PHP中的实际操作

3,PHP上传下载

2016-12-03  本文已影响137人  陈钢镚学财

前言


上传文件的应用场景很多,数不胜数,最典型的,就是图片上传了。
文件上传,可以简单的学,也可以复杂的学。可以知其然,也可以知其所以然。
网络上针对PHP的文件上传有许许多多的“实现”教程,但对于原理方面的讲解却很少。
所以本人自认为才思敏捷,便斗胆推敲一二。
觉得好的,捧场点赞皆可,觉得渣的,留言抨击亦可。
有不对的地方,还请大神指出。

接下来,本文就针对PHP文件上传的实现流程,来一一做出分析。

目录


  1. 简介

简书的markdown无法添加当页锚点,所以就不做跳转了。
(哪位前辈如果知道怎么添加,小弟跪求指教!)

简介


首先,我把整个上传流程中参与的角色都拎出来,再做一一分析。

本屌丝不才,文字讲解比较生硬,所以特献上一张流程图,来将此流程描述清楚。

PHP基于HTTP的文件上传.png

由上图可加,在这个流程之中,最关键的,就是文件流了。而文件流,则是在浏览器解析表单的时候,自动获取并提交的。
这也是为什么,有些人想要异步上传文件的时候,直接把form序列化或直接取input的value时,无法成功的原因了。
(异步上传的做法,本文暂不讨论)

$_FILES


这是PHP提供的一个预定义变量,格式是二维数组(并不一定)。

Array(
    input_name=>array(
        name=>上传的文件名,
        type=>上传的文件MIME类型,
        tmp_name=>上传服务器上的临时文件名
        size=>上传文件的大小
        error=>上传文件的错误号
    )
)

如上,是它的结构。
其中,input_name就是HTML表单中file框所指定的name值

$_FILES的结构是多变的,它并不永远都保持一个二维数组的样子。
如,你的file框开启了文件多选,又或者,你提交的一个表单中,存在好几个文件,具体结构,视情况而定。

php.ini的相关配置


// 直接配置
File_uploads = on 支持通过http上传文件

Upload_tmp_dir = , 临时文件存放目录

Upload_max_filesize = 2M 允许上传的最大值

Max_file_uploads=20 允许一次上传最大的文件数

Post_max_size=8M post方式发送数据的最大值

// 相关配置
max_execution_time = -1 设置了脚本被解析器终止之前,允许的最大执行时间,单位为秒

max_input_time = 60 脚本解析输入数据允许的最大时间,单位为秒

max_input_nesting_level = 64 设置输入变量的嵌套深度

max_input_vars = 1000 
接受多少输入的变量,限制分别应用于$_GET,$_POST和$_COOKIE
即,get和post最多只允许传入1000个变量

memory_limit = 128M 最大单线程独立的内存使用量

错误码


0:上传成功(上传到临时目录)
1:文件超过upload_max_filesize的限制
2:上传文件大小超过了HTML表单中MAX_FILE_SIZE指定的值
3:文件只有部分被上传
4:没有文件被上传
6:找不到临时文件夹
7:文件写入失败
8:上传的文件被PHP扩展程序中断

持久保存文件


实际上,在我们得到$_FILES之前的流程,在“简介”中,已经描述过了。
所以,排除上传出错的情况之外,我们已经知道,在截止到得到$_FILES这一步,上传的所有文件都还保存在临时目录里面。

既然称之为临时目录,那么我们的文件当然不能一直放在那里。
所以,我们需要将文件持久保存到符合我们系统逻辑的、正确的目录中。

这一步其实很简单,有两个方法:

方式一:move_uploaded_file($tmp_name,’uploads/’.’$filename’);
方式二:copy($tmp_name,’uploads/’.’$filename’);

但是你必须保证PHP所使用的帐号,有权限在该文件夹下写文件,特别是Linux系列的环境。

ThinkPHP upload 的成员


Upload.png

下载


主要用于提示浏览器,下载一些支持格式的文件,如html,php,png等
$filename = ’1.jpg’;
$file = ’./1.jpg’;
header(’content-disposition:attachment;filename=’.$file); // 下载时浏览器显示的文件名
header(’content-length:’.filesize($file));

结语


上传下载的应用非常广泛,实现层次,其实也不用重复造轮子,理解思路,再直接使用现成的类就可以了。

本文出自半醒的狐狸博客

上一篇 下一篇

猜你喜欢

热点阅读