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 相关文章推荐
PHP 字符截取 解决中文的截取问题,不用mb系列
Sep 29 PHP
phpmyadmin显示utf8_general_ci中文乱码的问题终级篇
Apr 08 PHP
php实现统计邮件大小的方法
Aug 06 PHP
php中通过curl检测页面是否被百度收录
Sep 27 PHP
yii2 RBAC使用DbManager实现后台权限判断的方法
Jul 23 PHP
Thinkphp连表查询及数据导出方法示例
Oct 15 PHP
PHP不使用内置函数实现字符串转整型的方法示例
Jul 03 PHP
thinkphp5 URL和路由的功能详解与实例
Dec 26 PHP
laravel项目利用twemproxy部署redis集群的完整步骤
May 11 PHP
PHP模版引擎原理、定义与用法实例
Mar 29 PHP
ThinkPHP3.2框架操作Redis的方法分析
May 05 PHP
PHP+MySQL实现在线测试答题实例
Jan 02 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
用PHP实现的四则运算表达式计算实现代码
2011/08/02 PHP
ThinkPHP框架使用redirect实现页面重定向的方法实例分析
2018/04/12 PHP
PHP PDOStatement::bindColumn讲解
2019/01/30 PHP
javascript知识点收藏
2007/02/22 Javascript
JAVASCRIPT style 中visibility和display之间的区别
2010/01/22 Javascript
jQuery 学习6 操纵元素显示效果的函数
2010/02/07 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
6款经典实用的jQuery小插件及源码(对话框/提示工具等等)
2013/02/04 Javascript
JS数组去重与取重的示例代码
2014/01/24 Javascript
JS对象与json字符串格式转换实例
2014/10/28 Javascript
快速学习AngularJs HTTP响应拦截器
2015/12/31 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
CheckBox多选取值及判断CheckBox选中是否为空的实例
2017/10/31 Javascript
js中url对象化管理分析
2017/12/29 Javascript
Vue中&quot;This dependency was not found&quot;问题的解决方法
2018/06/19 Javascript
vue.js层叠轮播效果的实例代码
2018/11/08 Javascript
vue.js实现的幻灯片功能示例
2019/01/18 Javascript
angular多语言配置详解
2019/05/16 Javascript
javascript刷新父页面方法汇总详解
2019/10/10 Javascript
Vue实现导航栏菜单
2020/08/19 Javascript
Python多线程编程(六):可重入锁RLock
2015/04/05 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
python  ceiling divide 除法向上取整(或小数向上取整)的实例
2019/12/27 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
学习Python需要哪些工具
2020/09/04 Python
Python descriptor(描述符)的实现
2020/11/15 Python
python中的unittest框架实例详解
2021/02/05 Python
聚网科技C++面试笔试题
2015/09/01 面试题
TCP/IP的分层模型
2013/10/27 面试题
法学毕业生自我鉴定
2014/01/31 职场文书
家长建议怎么写
2014/05/15 职场文书
小学关爱留守儿童活动方案
2014/08/25 职场文书
2014年教师节活动总结
2014/08/29 职场文书
机关职员工作检讨书
2014/10/23 职场文书
初中军训感言
2015/08/01 职场文书
apache ftpserver搭建ftp服务器
2022/05/20 Servers