yii2 Excel电子表格(xlsx格式)文件上传验证

Posted sjg20010414

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了yii2 Excel电子表格(xlsx格式)文件上传验证相关的知识,希望对你有一定的参考价值。

关键位置: vendor/yiisoft/validators/FileValidator.php

    protected function validateExtension($file)
    {
        $extension = mb_strtolower($file->extension, 'UTF-8');

        if ($this->checkExtensionByMimeType) {
            $mimeType = FileHelper::getMimeType($file->tempName, null, false);
            if ($mimeType === null) {
                return false;
            }

            $extensionsByMimeType = FileHelper::getExtensionsByMimeType($mimeType);

            if (!in_array($extension, $extensionsByMimeType, true)) {
                return false;
            }
        }

        if (!empty($this->extensions)) {
            foreach ((array) $this->extensions as $ext) {
                if ($extension === $ext || StringHelper::endsWith($file->name, ".$ext", false)) {
                    return true;
                }
            }
            return false;
        }

        return true;
    }

以上代码验证扩展名的流程是:得到上传的文件的(表面)扩展名 $extension,如果允许根据MIME类型检测扩展名,根据已经上传的临时文件获得它的MIME类型 $mimeType,根据 $mimeType 反向去获取可能的后缀 $extensionsByMimeType,如果上传文件的(表面)扩展名的确不在其内,验证失败(即认为那个文件只是伪造了后缀名来作为某种文件),反之,再进一步查验(表面)扩展名是否在模型配置中设定的允许扩展名之内(未配置则略过这一步)。

WPS电子表格文件,xlsx格式,上传后,根据文件推导的MIME类型为:

application/octet-stream

而 Microsoft Office Home and Student 2019 中 Excel 的电子表格文件, xlsx格式,上传后为:

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

Excel建立的文件,用WPS打开,另存为 xlsx 后,就变成 WPS 的 MIME 了。而 LibreOffice 电子表格另存为xlsx后,MIME 是 Excel 一致的。

另外一个 xlsx 文件,不清楚是用什么软件或哪个版本生成的,得到的 MIME 为

application/zip

微软自己的软件对 Excel xlsx电子表格的 MIME 描述最准确,因为它是从文档格式来说的,后面那个不知名软件搞出来的则完全把xlsx文件理解成 用zip压缩的一堆xml文件,这个范围就大了一点了,因为 Office 文件后缀最后带 x 的都是zip压缩的一堆xml文件,而WPS最笼统,直接成了二进制流文件,太多文件是这个东西了。

yii2 根据后缀推导 MIME 类型,内部主要使用 PHP 的 finfo_open 函数,如果要去找一个能够识别 WPS的 magic file,再重新去覆盖写一个 FileValidator,工程量太大。所以,我们采用简单的变通办法:

后端不检查后缀名,但检查 MIME 类型,检查后缀名的工作交给前端完成。

    /**
     * @var UploadedFile
     */
    public $excelFile;

    public function rules()
    {
        return [
            [['excelFile'], 'file', 'skipOnEmpty' => false, 'mimeTypes' => [
                'application/octet-stream',
                'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
                'application/zip',
            ]],
        ];
    }

以上是关于yii2 Excel电子表格(xlsx格式)文件上传验证的主要内容,如果未能解决你的问题,请参考以下文章

请问电子表格文件的后缀是 :xlsx 吗?

将 Excel XML 电子表格转换为 xlsx

使用 Python 打开 Excel 电子表格 (.xlsx)

excel表格xlsx格式文件打开后自动变成xlsm文件怎么回事?

Excel xls和xlsx有啥区别

怎么讲csv格式转换为xlsx