2017-06-12 15:47:55 6558次浏览 5条回答 1 悬赏 10 金钱

上传文件处理的UploadForm.php

<?php
namespace common\models;

use yii\base\Model;
use common\helpers\CommonFun;

class UploadForm extends Model
{
    const UPLOAD_FILE = 'file';//上传文件
    const UPLOAD_IMAGE = 'image';//上传图片

    public $inputFile;
    public $imageFile;

    public function scenarios()
    {
        return [
            self::UPLOAD_FILE => ['inputFile'],
            self::UPLOAD_IMAGE => ['imageFile'],
        ];
    }

    public function rules()
    {
        return [
            [
                ['inputFile'],
                'file',
                'skipOnEmpty' => false,
                'extensions' => ['txt', 'zip', 'pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', '7z', 'gz'],
                'on' => 'file'
            ],
            [
                ['imageFile'],
                'image',
                'skipOnEmpty' => false,
                'extensions' => 'png, jpg, gif, jpeg',
                'on' => 'image'
            ],
        ];
    }

    /**
     * upload file
     * @author 
     * @dateTime 2017-05-04T19:28:13+0800
     * @param    string $target the upload directory
     * @param    string $fileName the uploaded file name
     * @return   mix
     */
    public function upload($target = NULL,$fileName = NULL)
    {
        if ($this->validate()) {
            //$target = $target ? $target :  Yii::getAlias('@uploads') . '/'. date("Ym");
            if ($this->inputFile != NULL) {
                $extension = $this->inputFile->extension;
            } else {
                $extension = $this->imageFile->extension;
            }
            $target = $target ? $target : $this->setDefaultUploadDir($extension);
            $dir = getcwd() . '/' . $target;
            if(!file_exists($target)) {
                CommonFun::recursionMkDir($target);
            }
            $fileName = $fileName ? $fileName : CommonFun::createUniqueStr();
            $saveName = $dir . '/' . $fileName . '.' . $extension;
            if($this->inputFile != NULL) {
                $this->inputFile->saveAs($saveName);
            } else {
                $this->imageFile->saveAs($saveName);
            }
            $resultUrl = $target . '/' . $fileName . '.' . $extension;
            return $resultUrl;
        } else {
            return false;
        }
    }

    /**
     * 设置默认的上传目录
     * 根据各个应用生成目录
     * @author 
     * @dateTime 2017-05-24T09:21:38+0800
     * @return string 上传路径
     */
    public function setDefaultUploadDir($extension = NULL)
    {
        $uploadDir = "uploads/" . date("Ym");
        if ($extension) {
            $uploadDir .= '/'. $extension;
        }
        if(!file_exists($uploadDir)) {
            CommonFun::recursionMkDir($uploadDir);
        }
        return $uploadDir;
    }
}

上传文件为test.xlsx
wps版的mimeType为application/octet-stream
office版的mimeType为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
yii的验证机制是根据上传文件的mimeType来匹配对应的extension列表,然而xlsx已经被使用了,我不能再加个xlsx的键值对
在不改源码的基础上怎么让wps文件通过FileValidator的验证

补充于 2017-06-12 16:02

wps的excel表格的mimeType为application/octet-stream
在yii2/helpers/mimeTypes.php中application/octet-stream对应的key是
["bin","bpk","deploy","dist","distz","dms","dump","elc","lrf","mar","pkg","so"]
并没有xlsx,所以认为上传文件是不合法的

补充于 2017-06-12 16:13

好的,多谢,我看看还有没有好的方法

最佳答案

  • 回答于 2017-06-12 15:54 举报

    ??????????

  • 回答于 2017-06-12 16:01 举报

    我做Excel的时候也发现了这个问题,后来我把验证规则MimeType验证关闭了.
    后来自己根据文件类型写了个验证规则
    这是我的验证规则

    [['excelFile'], 'file', 'skipOnEmpty' => true, 'checkExtensionByMimeType' => false, 'extensions' => 'xls,xlsx'],
    
    6 条回复
    回复于 2017-06-12 16:03 回复

    把这个checkExtensionByMimeType设置成false就可以过了,想做的更严谨一些自己写了一个checkExcelFileMime方法

    回复于 2017-06-12 16:04 回复

    怎么实现的,我看到你的验证的还是file

    回复于 2017-06-12 16:04 回复

    这样的话extensions就完全不验证了

    回复于 2017-06-12 16:07 回复

    要不然你就该底层,我找了,被占用了,感觉改了不太好,我这边Excel模板是固定,我把MimeType抓出来自己写的方法验证的

    回复于 2017-06-12 16:07 回复

    按照我的想法最好时能够把mimeTypes.php中的key对应的value改成数组
    'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/octet-stream'),

    但是我就是不太清楚怎么在不改变源码的基础上实现,刚使用yii不久

    回复于 2017-06-12 16:12 回复

    我也刚用了个把月,不想动底层的东西,你可以研究一下

  • 回答于 2017-06-12 16:09 举报

    这是我抓的我mime,自己简单写了个方法,虽然受限制,但是对我项目实用

    /**
         * 校验Excel mime类型
         * @return bool
         */
        public function checkExcelFileMime()
        {
            $excel_mime_hash = [
                'application/vnd.ms-excel',
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            ];
            if (in_array($this->excelFile->type, $excel_mime_hash, true)) {
                return true;
            }
            return false;
        }
    
    1 条回复
    回复于 2017-06-12 16:16 回复

    好的,多谢解答,我先看看还有没有好的方法

  • 回答于 2017-06-12 16:17 举报

    源码是这么对应的

    'xls' => 'application/vnd.ms-excel',
    'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroenabled.12',
    'xlsm' => 'application/vnd.ms-excel.sheet.macroenabled.12',
    'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    
您需要登录后才可以回答。登录 | 立即注册
bzzear
总监

bzzear

注册时间:2017-04-20
最后登录:2021-04-18
在线时长:42小时17分
  • 粉丝8
  • 金钱3110
  • 威望80
  • 积分4330

热门问题