0

我有一个允许用户上传电子表格的工具,然后我用 Laravel-Excel 解析电子表格。我的问题是,如何在尝试解析文件之前检查该文件是否为有效的 excel 文件?

我查看了 PHPOffice/Laravel-Excel 文档,但找不到验证文件的方法。所以,我的下一个猜测是,如果我尝试 Load() 一个无效文件,它会爆炸并给我一个警告或错误。但是,它不会这样做,而是解析文件并尝试以某种方式将其转换为电子表格。例如,我给它提供了一个 pdf,它确实生成了一个集合,其中包含它可以在 pdf 文件中找到的任何非二进制垃圾。这是不可取的。

目前,我正在进行 mime 类型检查以验证文件。

//valid mime types

$mimeTypes = [
    'application/csv', 'application/excel',
    'application/vnd.ms-excel', 'application/vnd.msexcel',
    'text/csv', 'text/anytext', 'text/plain', 'text/x-c', 
    'text/comma-separated-values',
    'inode/x-empty',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
             ];
$file = request()->hasFile('file');
if ($file) {
    if (in_array(request()->file('file')->getClientMimeType(), $mimeTypes)) {
        //then parse the file
        Config::set('excel.import.heading', 'original');
        $data = Excel::load(request()->file('file')->path(), function ($reader) {
        })->get();
         //do some stuff with data...
    } else {
        //invalid file
    }
} else {
    //no file uploaded
}

这并不理想,因为似乎有各种各样的可能的 mime 类型,所以我必须积极维护列表,并且某些 csv 文件具有纯文本 mime 类型,因此非 csv-plaintext 文件将在这里通过集合. Laravel、Laravel-Excel 或 PHPOffice 是否提供任何标准方法来验证文件?

4

1 回答 1

0

这不是对文件的 MIME 检查!

您只是在此处检查用户提供的文件扩展名信息。

string|null getClientMimeType()

返回文件 mime 类型。

客户端 mime 类型是从上传文件的请求中提取的,因此不应将其视为安全值

对于受信任的 mime 类型,请改用 getMimeType()(它会根据文件内容猜测 mime 类型)。

Symfony 组件 HttpFoundation 文件 UploadedFile

如果您想验证上传文件本身中的魔法 MIME 字节,您可以依靠您的操作系统的魔法 MIME 字节文件来做到这一点,就像 PHP 中这样。

$finfo = finfo_open(FILEINFO_MIME_TYPE); // return mime type ala mimetype extension
// $mime will contain the correct mime type
$mime = finfo_file($finfo, $_FILES['your-form-upload-input-name-here']['tmp_name'];
finfo_close($finfo);

有关finfo_file更多详细信息,请参阅。

要专门使用您当前依赖的 Symfony 组件来执行此操作,请getMimeType()改为调用该方法。请注意,不同之处在于它getClientMimeType()使用了客户端提供的不可信任的信息,而执行与上面getMimeType()演示的相同的操作。finfo_file()

于 2016-09-09T19:07:18.643 回答