php文件上传后端处理小技巧

本文就来说说,php文件上传后端处理都有些什么技巧吧!

业务场景一、我们只会选择一个单个的文件上传,而且不需要做一些即时的验证工作。那么,也许并没有什么优化可言了,因为,最后你要做的,只是将这个文件放在表单里最后一起提交,直接处理即可!

业务场景二、需要上传多个文件,而且需要时时验证文件内部内容,并时行相应页面显示。对于这种况,在用户选择了上传文件之后,我们需要立即将文件上传,因为我们需要读取文件里的信息,在最后提交的时候,我们也需要提交一次文件。很明显,在这里是存在一个重复上传的工作的,一个耗费用户时间,二个是耗费服务器带宽资源!优化,能够想得到的方法也很简单,能不能在第一次上传完文件之后,就将文件保留在服务器,真正提交表单的时候,去读取这个已经被上传的临时文件即可。是的,这就是我们的处理思路!

业务场景三、与场景二类似,需要上传多个文件,但是多个文件可能是分开上传的。即我们可能第一次上传了10M,第二次上传了10M,总共上传了10次,那么,在服务器端来说的话,一次性提交肯定是超出了上传大小的限制了,但是如果,我们是分每一次的上传,这是可以的,而最后提交的时候,我们只需要将简短的文本信息传上去即可!

  思路的确是简单的,看起来,也是没什么问题,但是,也许我是能力有限,当时着实花了我不少时间去处理这个什么鬼!下面,我将给出一些示例代码,以供参考:

文件上传技巧(将单次上传的文件作为临时文件存在在服务器端)示例代码:

1. 页面js处理

    //点击选择完成文件后,触发上传文件操作,将文件上传至服务器临时目录
    $('.upload-real-file').off().on('change', function(){
      if(!$(this).val()){
        return false;
      }
      var responseObjId = $(this).attr('response-id');
      var responseObj = $('#' + responseObjId);
      $('#Form').ajaxSubmit({
        url:'/aa/bb/uploadTmpApkTool',
        resetForm: false,
        dataType: 'json',
        beforeSubmit: function(option){
          window.loading = layer.load(2);
        },
        success: function(data, statusText){
          layer.close(window.loading);
          if(data.status == 1){
            responseObj.html(data.apkInfoHtml);
            var parentContainer = responseObj.parent().parent(),
              nameContainer = parentContainer.find('.file-name-container');
            nameContainer.html(data.apkName);
            nameContainer.attr('title', data.apkName);
            responseObj.find('.file-tmp').html(data.fileInfo); //将文件信息存放于隐藏域中,以便在提交时能找到
            $(submitId).removeAttr('disabled');
          }else{
            layer.alert(data.info);
          }
        },
        error: function(data){
          layer.close(window.loading);
          layer.alert('未知错误,请稍后再试!');
        }
      });
      return false;//防止dialog 自动关闭
    });

2. 很明显,页面里面需要获取文件信息,后台处理代码(PHP)

    $apkConfig = $this->_getApkConfig();
    $params = $this->getFilteredParam('get');
    $subFile = $_FILES['apkToolFiles'];
    $apkName = $apkInfoHtml = "";
    if(empty($subFile))
    {
      $this->ajaxReturn(array('status' => -4, 'info' => '请选择要上传的文件'));
    }

    foreach ($subFile['name'] as $subKey => $subVal)
    {
      if ($subFile['name'][$subKey])
      {
        $fileData = $this->_getFileData($subFile, $subKey);
        $checkData = array(
          'maxSize' => $apkConfig['FILE_MAX_SIZE'],
          'savePath' => $apkConfig['TMP_CHILD_PATH'],
          'extArr' => array('apk'),
          'releaseName' => str_replace('.apk', '', $fileData['fileName']), //特有
        );
        $checkResult = $this->_checkFileData($fileData, $checkData);
        if ($checkResult['status'] != 1)
        {
          $this->ajaxReturn($checkResult);
        }
        //移动文件
        $filePath = $checkData['savePath'] . '/' . $fileData['fileName'] . '.tmp' . genRandStr(6);;
        $this->_moveUploadedFile($fileData['tmpName'], $filePath);
        $apkInfo = $this->_apkParser($filePath); //解析
        if($apkInfo['UMENG_CHANNEL'] != 'UMENG_CHANNEL_VALUE')
        {
          @unlink($filePath);               //删除无效文件
          $this->ajaxReturn(array('status' => 0, 'info' => "UMENG_CHANNEL的值要是 UMENG_CHANNEL_VALUE才行"));
        }
        $tmpFileArr['file_info'] = array(
          'name' => $subFile['name'][$subKey],
          'type' => $subFile['type'][$subKey],
          'tmp_name' => str_replace($apkConfig['TMP_CHILD_PATH'] . '/', '', $filePath),
          'error' => $subFile['error'][$subKey],
          'size' => $subFile['size'][$subKey],
        );       //转存该值,不再重复上传文件
      }
      else
      {
        $this->ajaxReturn(array('status' => 0, 'info' => "文件不能为空"));
      }
      foreach ($apkInfo as $key => $val)
      {
        $apkInfoHtml .= "{$key}:{$val} \r\n";
      }
      $apkName = $fileData['fileName'];
      $version = $apkInfo['versionName'];
    }
    $fileInfo = htmlspecialchars(json_encode($tmpFileArr['file_info']));
    $fileInfoHtml = "<input name=\"apkToolFileTmp[]\" value='{$fileInfo}' type=\"hidden\"/>";  //一定要输出前使用htmlspecialchars, 否则不能正确显示页面值和获取至正确的文件信息

    $this->ajaxReturn(array('status' => 1, 'info' => "上传成功", 'version' => $version, 'item' => $item, 'apkName' => $apkName, 'apkInfoHtml' => $apkInfoHtml, 'fileInfo' => $fileInfoHtml));
  }

3. 通过以两部分代码的配合,我们在页面上已经有正确的信息了,只需要在最后提交表单的时候,不要将文件提交到服务器,在服务器端处理时,只需将之前上传的临时文件移动一下位置即可,这样就算大功告成了!

$('.upload-file-real').attr('disabled', 'disabled');        //提交表单前,禁用上传文件

4. 后续工作

将临时文件上传到服务器后,是没办法判断用户是否取消当前操作的,如果取消了,则临时文件将一直存在于服务器,所以,我们需要一个定时清理临时目录的脚本。当然,这个很简单,就只需要找到这个目录,比较一下时间,比如超过一天前的文件就给删除。注意控制清理频率即可!

5. 题外话

日志真的很重要,哪里出错了,哪里删除文件了,哪里清理数据库了,一定要做好记录!  

上传文件到服务器临时目录,后端处理原理看起来很简单,但是也需要你仔细调试,至少当初我在做这个小功能时,着实费了不少劲才缕清楚的!

以上就是本文的全部内容,希望大家可以掌握php文件上传后端处理的技巧,谢谢大家的阅读。

(0)

相关推荐

  • PHP MVC框架skymvc支持多文件上传

    本文实例为大家分享了skymvc实现文件上传的具体代码,供大家参考,具体内容如下 1.代码upload.ctrl.php <?php class uploadControl extends skymvc{ public function __construct(){ parent::__construct(); } public function onDefault(){ $this->smarty->display("upload/default.html"); }

  • 你不知道的文件上传漏洞php代码分析

    漏洞描述 开发中文件上传功能很常见,作为开发者,在完成功能的基础上我们一般也要做好安全防护. 文件处理一般包含两项功能,用户上传和展示文件,如上传头像. 文件上传攻击示例 upload.php <?php $uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['userfile']['name']); if (move_uploaded_file($_FILES['userfile']['tmp_name'],

  • php ajax实现文件上传进度条

    本实例是关于php文件上传时进度条的实现,主要采用ajax技术,另外还运用了html5,有需要的朋友可以研究一下. 本实例有两个文件: upload_form.html: <!DOCTYPE html> <html> <head> <script> function _(el){ return document.getElementById(el); } function uploadFile(){ var file = _("file1"

  • PHP实现文件上传和多文件上传

    在PHP程序开发中,文件上传是一个使用非常普遍的功能,也是PHP程序员的必备技能之一.值得高兴的是,在PHP中实现文件上传功能要比在Java.C#等语言中简单得多.下面我们结合具体的代码实例来详细介绍如何通过PHP实现文件上传和多文件上传功能. 要使用PHP实现文件上传功能,我们先来编写两个php文件:index.php和upload.php.其中,index.php页面用于提交文件上传的表单请求,upload.php页面用于接收上传的文件并进行相应处理. 首先,我们来编写一个简单的index.

  • php文件上传你必须知道的几点

    本篇文章主要说明的是与php文件上传的相关配置的知识点.PHP文件上传功能配置主要涉及php.ini配置文件中的upload_tmp_dir.upload_max_filesize.post_max_size等选项,下面一一说明. 打开php.ini配置文件找到File Uploads file_uploads = On 默认允许HTTP文件上传,此选项不能设置为OFF. upload_tmp_dir = 默认为空,此选项在手动配置PHP运行环境时,也容易遗忘,如果不配置这个选项,文件上传功能就

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

    文件上传一般有下面2种方式: 有两种: 1.标准input表单方式,典型的用$_FILES进行接收: 2.以Base64的方式进行传送,一般是AJAX异步上传. 第一种 标准的input表单方式,适用于大文件进行上传,同时支持批量.html代码关键的几句: <form enctype="multipart/form-data" method="post" action="upload.php""> <input typ

  • 功能强大的php文件上传类

    本文实例为大家分享了php文件上传类,功能很强大,供大家参考,具体内容如下 <?PHP /* *文件上传类 **/ class upfile{ private $file_size;//上传源文件大小 private $file_tem;//上传文件临时储存名 private $file_name;//上传文件名 private $file_type;//上传文件类型 private $file_max_size=2000000;//允许文件上传最大 private $file_folder=&qu

  • php文件上传 你真的掌握了吗

    这里首先声明一下这一章的内容比较多,比较难,你要抱着和自己死磕的态度.细微之处不放过,多敲多练是王道. 学习就像爬山,得一步一步来,首先给自己定一个小目标,然后再坚持不懈地往高出攀爬,最终到达最顶峰. 请仔细斟酌上面两句忠告 一.我的准备情况说明. 编辑器:sublime text3(用什么编辑器看自己爱好) 服务器构建:使用phpstudy2014构建服务器,服务器文件存储在我自身电脑D盘的www文件中.(安装phpstudy会自动生成www文件,安装在哪个盘自己做主).运行phpstudy,

  • PHP利用APC模块实现大文件上传进度条的方法

    php 大文件带进度的上传,一直是一个令php程序员很苦恼的问题.查询baidu .Google ,大体做带进度的上传方式为:flash+php,socket,apc+php等,下面我介绍了apc +php+ajax制作的带进度的上传,并贴出源码,希望对大家有用. Alternative PHP Cache(APC)是 PHP 的一个免费公开的优化代码缓存.它用来提供免费,公开并且强健的架构来缓存和优化 PHP 的中间代码. 在使用apc时候,先必须使用安装apc 模块. 第一步:下载php_a

  • php处理单文件、多文件上传代码分享

    php处理  单文件.多文件上传实例代码,供大家参考,具体内容如下 后台处理文件submit_form_process.php <?php /****************************************************************************** 参数说明: $max_file_size : 上传文件大小限制, 单位BYTE $destination_folder : 上传文件路径 $watermark : 是否附加水印(1为加水印,其他为不加

随机推荐