>[danger] 先来看最基本的文件上传表单,以及服务器接收到的数据结构
a.php
~~~
<?php
if ($_POST) {
echo '<pre>';
print_r($_POST);
echo '</pre>';
echo '<hr>';
echo '<pre>';
print_r($_FILES);
echo '</pre>';
exit;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="keywords" content="keywords">
<meta name="description" content="description">
<link href="favicon.ico" rel="icon" type="image/x-icon">
<link href="" type="text/css" rel="stylesheet">
<script src=""></script>
<title>Document</title>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data">
<input type="text" name="val" value="val"><br />
<input type="file" name="logo"><br />
<input type="file" name="pic"><br />
<input type="file" name="list[]"><br />
<input type="file" name="list[]"><br />
<input type="file" name="img-list[]"><br />
<input type="file" name="img-list[]"><br /><br />
<!-- 如果有name有值,则就会有一个$_POST[s] = 提交的值 -->
<input type="submit" name="s" value="提交"><br />
<!-- 没有提交效果 -->
<input type="button" name="b" value="提交按钮"><br />
<!-- 在form中有提交效果,type="submit" 也有提交效果,但是 type="button" 就没有提交效果了 (注意所有的提交按钮必须在form中才能提交除非用js控制) -->
<button>按钮</button>
</form>
</body>
</html>
~~~
![](https://box.kancloud.cn/992ce43b78c6c6e30255b27d67dc0714_314x280.jpg)
点击 提交 :
~~~
Array
(
[val] => val
[s] => 提交
)
Array
(
[logo] => Array
(
[name] => QQ图片20161106223133.jpg
[type] => image/jpeg
[tmp_name] => D:\wamp64\tmp\php92D0.tmp
[error] => 0
[size] => 217991
)
[pic] => Array
(
[name] => QQ图片20161106223133.jpg
[type] => image/jpeg
[tmp_name] => D:\wamp64\tmp\php931F.tmp
[error] => 0
[size] => 217991
)
[list] => Array
(
[name] => Array
(
[0] => QQ图片20161106223133.jpg
[1] => fdc20716fe1372b0859ec0019d7e6194.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => D:\wamp64\tmp\php932F.tmp
[1] => D:\wamp64\tmp\php9350.tmp
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 217991
[1] => 6768
)
)
[img-list] => Array
(
[name] => Array
(
[0] => QQ图片20161106223133.jpg
[1] => bg-01.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => D:\wamp64\tmp\php9351.tmp
[1] => D:\wamp64\tmp\php9361.tmp
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 217991
[1] => 471588
)
)
)
~~~
**上面就是所有最基本的表单上传,最基本的上传数据结构了。**
文件上传根据类型,可分为两种:
- **单文件上传**
- 单一字段
- **多文件上传**
- 多字段的形式多文件
- 单一字段数组(img[])的形式多文件上传**(这种最复杂,注意这种形式的数据结构)**
- 组合多文件(上面几种情况的组合)
参考:
[修复Request->file()判断临时文件不严谨导致多文件上传失败的情况](https://github.com/top-think/framework/pull/348)
[文件上传那些事儿](https://mp.weixin.qq.com/s/ni_5rZDCOypxtHrVXq1Aww)
### 扩展
~~~html
<input type="file" multiple name="pic[]">
~~~
`multiple`是HTML5新增的属性,这个属性可以使上传表单上传时选择多个文件,点击“选择文件”,在弹出系统选择文件窗口中按住`Ctrl`键可以连续选择多个文件,**但是此属性必须配合pic[]数组字段的形式才有作用(注意有些上传插件比如uploadify,这些可以选择多文件上传,此时可能也有这个问题,注意检查上传字段名的设置)**,否则即使选择多个文件,提交到服务器也只有最后一个选择的文件。(所以这个属性可以用来避免以前上传多文件需要多表单,仅一个表单就搞定了)
* * * * *
### 其他
对于前端来说,图片上传有以下知识点:
- 普通上传
- ajax无刷新文件上传
- 大文件分块上传
- MD5提前校验去重,存在不上传(传到服务端再校验用处不大,只是节省空间,但是并没有节省不必要上传的流量)
- 图像压缩上传
- 图像裁剪(放大,缩小,旋转等手势操作)
这些操作以前只有flash才能全部做到,现在html5的新API也能够做到了,不过大部分接口对浏览器的版本要求比较高。
服务端收到文件的方式无非两种:
1. 普通的$\_FIELS
2. base64编码的字符图片$\_POST(非常规Coentent-Type时用`file_get_contents('php://input', 'r')`)
**参考:**
[php://input - 简单--生活 - 博客园](http://www.cnblogs.com/xiangxiaodong/archive/2012/11/07/2758685.html)
[PHP: php:// - Manual](http://php.net/manual/zh/wrappers.php.php)
* * * * *
[Http 历险记(上)](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513069&idx=1&sn=548c497c46c7c076145064a120c7c101&scene=21#wechat_redirect)
[Http历险记(下)-- Struts的秘密](https://mp.weixin.qq.com/s?__biz=MzAxOTc0NzExNg==&mid=2665513080&idx=1&sn=d24a4cdfc71412c581393d584fd91326&scene=21#wechat_redirect)
* * * * *
last update:2017-8-17 09:45:38
- 开始
- 公益
- 更好的使用看云
- 推荐书单
- 优秀资源整理
- 技术文章写作规范
- SublimeText - 编码利器
- PSR-0/PSR-4命名标准
- php的多进程实验分析
- 高级PHP
- 进程
- 信号
- 事件
- IO模型
- 同步、异步
- socket
- Swoole
- PHP扩展
- Composer
- easyswoole
- php多线程
- 守护程序
- 文件锁
- s-socket
- aphp
- 队列&并发
- 队列
- 讲个故事
- 如何最大效率的问题
- 访问式的web服务(一)
- 访问式的web服务(二)
- 请求
- 浏览器访问阻塞问题
- Swoole
- 你必须理解的计算机核心概念 - 码农翻身
- CPU阿甘 - 码农翻身
- 异步通知,那我要怎么通知你啊?
- 实时操作系统
- 深入实时 Linux
- Redis 实现队列
- redis与队列
- 定时-时钟-阻塞
- 计算机的生命
- 多进程/多线程
- 进程通信
- 拜占庭将军问题深入探讨
- JAVA CAS原理深度分析
- 队列的思考
- 走进并发的世界
- 锁
- 事务笔记
- 并发问题带来的后果
- 为什么说乐观锁是安全的
- 内存锁与内存事务 - 刘小兵2014
- 加锁还是不加锁,这是一个问题 - 码农翻身
- 编程世界的那把锁 - 码农翻身
- 如何保证万无一失
- 传统事务与柔性事务
- 大白话搞懂什么是同步/异步/阻塞/非阻塞
- redis实现锁
- 浅谈mysql事务
- PHP异常
- php错误
- 文件加载
- 路由与伪静态
- URL模式之分析
- 字符串处理
- 正则表达式
- 数组合并与+
- 文件上传
- 常用验证与过滤
- 记录
- 趣图
- foreach需要注意的问题
- Discuz!笔记
- 程序设计思维
- 抽象与具体
- 配置
- 关于如何学习的思考
- 编程思维
- 谈编程
- 如何安全的修改对象
- 临时
- 临时笔记
- 透过问题看本质
- 程序后门
- 边界检查
- session
- 安全
- 王垠
- 第三方数据接口
- 验证码问题
- 还是少不了虚拟机
- 程序员如何谈恋爱
- 程序员为什么要一直改BUG,为什么不能一次性把代码写好?
- 碎碎念
- 算法
- 实用代码
- 相对私密与绝对私密
- 学习目标
- 随记
- 编程小知识
- foo
- 落盘
- URL编码的思考
- 字符编码
- Elasticsearch
- TCP-IP协议
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依赖注入
- 开发笔记
- 经纬度格式转换
- php时区问题
- 解决本地开发时调用远程AIP跨域问题
- 后期静态绑定
- 谈tp的跳转提示页面
- 无限分类问题
- 生成微缩图
- MVC名词
- MVC架构
- 也许模块不是唯一的答案
- 哈希算法
- 开发后台
- 软件设计架构
- mysql表字段设计
- 上传表如何设计
- 二开心得
- awesomes-tables
- 安全的代码部署
- 微信开发笔记
- 账户授权相关
- 小程序获取是否关注其公众号
- 支付相关
- 提交订单
- 微信支付笔记
- 支付接口笔记
- 支付中心开发
- 下单与支付
- 支付流程设计
- 订单与支付设计
- 敏感操作验证
- 排序设计
- 代码的运行环境
- 搜索关键字的显示处理
- 接口异步更新ip信息
- 图片处理
- 项目搭建
- 阅读文档的新方式
- mysql_insert_id并发问题思考
- 行锁注意事项
- 细节注意
- 如何处理用户的输入
- 不可见的字符
- 抽奖
- 时间处理
- 应用开发实战
- python 学习记录
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文档相似度验证
- thinkphp5.0数据库与模型的研究
- workerman进程管理
- workerman网络分析
- java学习记录
- docker
- 笔记
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京东
- pc_detailpage_wareBusiness
- doc
- 电商网站设计
- iwebshop
- 商品规格分析
- 商品属性分析
- tpshop
- 商品规格分析
- 商品属性分析
- 电商表设计
- 设计记录
- 优惠券
- 生成唯一订单号
- 购物车技术
- 分类与类型
- 微信登录与绑定
- 京东到家库存系统架构设计
- crmeb
- 命名规范
- Nginx https配置
- 关于人工智能
- 从人的思考方式到二叉树
- 架构
- 今日有感
- 文章保存
- 安全背后: 浏览器是如何校验证书的
- 避不开的分布式事务
- devops自动化运维、部署、测试的最后一公里 —— ApiFox 云时代的接口管理工具
- 找到自己今生要做的事
- 自动化生活
- 开源与浆果
- Apifox: API 接口自动化测试指南