php文件上传的两种实现方法


Posted in PHP onApril 04, 2016

文件上传一般有下面2种方式:

有两种:
1、标准input表单方式,典型的用$_FILES进行接收;
2、以Base64的方式进行传送,一般是AJAX异步上传。

第一种
标准的input表单方式,适用于大文件进行上传,同时支持批量。html代码关键的几句:

<form enctype="multipart/form-data" method="post" action="upload.php"">
  <input type="file" name="id_pic[]" accept="image/*" class="form-control" multiple />
  <input type="submit" value="上传 " />
</form>

不同的name时:

<form enctype="multipart/form-data" method="post" action="upload.php"">
  <input type="file" name="id_pic_1" accept="image/*" class="form-control" />
  <input type="file" name="id_pic_2" accept="image/*" class="form-control" />
  <input type="submit" value="上传 " />
</form>

其中enctype="multipart/form-data"对于文件上传是必不可少的。另外type="file"设置input类型,accept="image/*"指定优先上传图片(MIME 参考手册)。multiple支持一次选多个文件,pic[]以数组的形式接收多个文件。手机端端还可以加入参数capture="camera"选择摄像头拍照上传。

后端处理:
通过$_FILES获取上传的文件。

$files = $_FILES;
传多个文件时,如果name不同,则返回的$_FILES数组格式不同。

name相同时:

array(1) {
 ["id_pic"] => array(5) {
  ["name"] => array(2) {
   [0] => string(5) "1.jpg"
   [1] => string(5) "2.jpg"
  }
  ["type"] => array(2) {
   [0] => string(10) "image/jpeg"
   [1] => string(10) "image/jpeg"
  }
  ["tmp_name"] => array(2) {
   [0] => string(27) "C:\Windows\Temp\php7A7E.tmp"
   [1] => string(27) "C:\Windows\Temp\php7A7F.tmp"
  }
  ["error"] => array(2) {
   [0] => int(0)
   [1] => int(0)
  }
  ["size"] => array(2) {
   [0] => int(77357)
   [1] => int(56720)
  }
 }
}

name不相同时:

array(2) {
 ["id_pic_1"] => array(5) {
  ["name"] => string(5) "1.jpg"
  ["type"] => string(10) "image/jpeg"
  ["tmp_name"] => string(27) "C:\Windows\Temp\phpBBEE.tmp"
  ["error"] => int(0)
  ["size"] => int(77357)
 }
 ["id_pic_2"] => array(5) {
  ["name"] => string(5) "2.jpg"
  ["type"] => string(10) "image/jpeg"
  ["tmp_name"] => string(27) "C:\Windows\Temp\phpBBEF.tmp"
  ["error"] => int(0)
  ["size"] => int(56720)
 }
}

在对$_FILES进行foreach遍历时,前面那种输出格式不大方便。后面那种就可以直接遍历。我们可以写个方法进行统一转换:

function dealFiles($files) {
    $fileArray = array();
    $n     = 0;
    foreach ($files as $key=>$file){
      if(is_array($file['name'])) {
        $keys    =  array_keys($file);
        $count   =  count($file['name']);
        for ($i=0; $i<$count; $i++) {
          $fileArray[$n]['key'] = $key;
          foreach ($keys as $_key){
            $fileArray[$n][$_key] = $file[$_key][$i];
          }
          $n++;
        }
      }else{
        $fileArray = $files;
        break;
      }
    }
    return $fileArray;
 }

好,前面讲到后端如何处理接收到的$_FILES数组,并转换成统一格式。接下来任务主要是:
1、检测上传的文件是否非法;
2、检测上传的文件是否超过大小;
3、检测保存的路径是否存在,是否可写;
4、文件重命名;

其中上传过程中用到了个很重要的函数:move_uploaded_file(filename , $destination )进行文件移动操作。将$_FILES['id_pic']['tmp_name']移动到新的路径里。当然,移动前可以用is_uploaded_file($_FILES['id_pic']['tmp_name'])进行判断文件是否正常上传的。

多文件上传则是循环的方法多次使用move_uploaded_file()进行移动操作。

第二种
主要以上传图片为主。
利用input的change事件,借助canvas对图片进行处理(例如压缩),然后ajax发送文件流到后端。

基本原理是通过canvas渲染图片,再通过 toDataURL 方法压缩保存为base64字符串(能够编译为jpg格式的图片)。

后端处理:
后端最终会收到前端发送的base64字符串,接着处理字符串为图片即可。具体请使用关键字base64 转 image 开发语言进行谷歌|百度。前端生成的结果中有一个base64Len,这是字符串的长度,后端应该核对以确认是否提交完整。

//php示例:
$img = base64_decode($_POST['img']);
$img = imagecreatefromstring($img);

以上就是本文的全部内容,希望对大家的学习有所帮助。

PHP 相关文章推荐
不用数据库的多用户文件自由上传投票系统(3)
Oct 09 PHP
中英文字符串翻转函数
Dec 09 PHP
比较strtr, str_replace和preg_replace三个函数的效率
Jun 26 PHP
关于PHP的curl开启问题探讨
Apr 08 PHP
微信API接口大全
Apr 15 PHP
php使用curl打开https网站的方法
Jun 17 PHP
PHP的Yii框架中过滤器相关的使用总结
Mar 29 PHP
postfixadmin忘记密码后的修改密码方法详解
Jul 20 PHP
利用PHP判断文件是否为图片的方法总结
Jan 06 PHP
thinkphp关于简单的权限判定方法
Apr 03 PHP
浅谈Laravel队列实现原理解决问题记录
Aug 19 PHP
解决laravel5中auth用户登录其他页面获取不到登录信息的问题
Oct 08 PHP
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
Apr 04 #PHP
PHP版本的选择5.2.17 5.3.27 5.3.28 5.4 5.5兼容性问题分析
Apr 04 #PHP
PHP命名空间和自动加载类
Apr 03 #PHP
PHP中的Trait 特性及作用
Apr 03 #PHP
PHP错误处理函数
Apr 03 #PHP
php通过curl添加cookie伪造登陆抓取数据的方法
Apr 02 #PHP
PHP函数nl2br()与自定义函数nl2p()换行用法分析
Apr 02 #PHP
You might like
Thinkphp 框架配置操作之动态配置、扩展配置及批量配置实例分析
2020/05/15 PHP
alert出数组中的随即值代码
2014/09/25 Javascript
jQuery中:nth-child选择器用法实例
2014/12/31 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
JavaScript 七大技巧(二)
2015/12/13 Javascript
DOM操作和jQuery实现选项移动操作的简单实例
2016/06/07 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
jQuery向webApi提交post json数据
2017/01/16 Javascript
JavaScript之事件委托实例(附原生js和jQuery代码)
2017/07/22 jQuery
jQuery实现的页面详情展开收起功能示例
2018/06/11 jQuery
微信小程序wx:for循环的实例详解
2018/10/07 Javascript
JavaScript使用闭包模仿块级作用域操作示例
2019/01/21 Javascript
微信小程序页面传多个参数跳转页面的实现方法
2019/05/17 Javascript
微信小程序实现聊天室
2020/08/21 Javascript
SpringBoot+Vue开发之Login校验规则、实现登录和重置事件
2020/10/19 Javascript
vue使用lodop打印控件实现浏览器兼容打印的方法
2021/02/07 Vue.js
[03:57]2016完美“圣”典风云人物:rOtk专访
2016/12/09 DOTA
python通过shutil实现快速文件复制的方法
2015/03/14 Python
几个提升Python运行效率的方法之间的对比
2015/04/03 Python
Python解析nginx日志文件
2015/05/11 Python
Python实现字典的key和values的交换
2015/08/04 Python
理解Python垃圾回收机制
2016/02/12 Python
Python实现学校管理系统
2018/01/11 Python
终端命令查看TensorFlow版本号及路径的方法
2018/06/13 Python
详解Python安装scrapy的正确姿势
2018/06/26 Python
python 初始化一个定长的数组实例
2019/12/02 Python
Python中logger日志模块详解
2020/08/04 Python
python 基于UDP协议套接字通信的实现
2021/01/22 Python
详解px单位html5响应式方案
2018/03/08 HTML / CSS
瑞典廉价机票预订网站:Seat24
2018/06/19 全球购物
全球性的众包图形设计市场:DesignCrowd
2021/02/02 全球购物
一套带答案的C++笔试题
2014/01/10 面试题
质量月口号
2014/06/20 职场文书
80后婚前协议书范本
2014/10/24 职场文书
2014年前台文员工作总结
2014/12/08 职场文书
Win10鼠标轨迹怎么开 Win10显示鼠标轨迹方法
2022/04/06 数码科技