【问题标题】:DOCX File type in PHP finfo_file is application/zipPHP finfo_file 中的 DOCX 文件类型为 application/zip
【发布时间】:2011-09-29 12:37:21
【问题描述】:

您好,我正在尝试通过 finfo_file 函数验证上传的文件类型。

但是当发送一个.docx文件时,文件类型是:

application/zip

代替:

application/vnd.openxmlformats-officedocument.wordprocessingml.document

我怎样才能改变这种行为?

【问题讨论】:

  • 实际上,新的 \w{3}x 格式是压缩的 XML。您可以将结尾更改为 .zip 并提取它们。我知道这无济于事,但很高兴知道:D
  • 提取文件进行测试真的不是解决办法
  • 文件的类型 zip。如果您想知道内容的类型/格式,则无法in查看它。
  • 我同意这是可以接受的,但仅限于小型应用程序,我暂时使用检查文件是否是来自 finfo_file 的“应用程序/zip”和来自 $_FILES[“file”的“应用程序/vnd.openxmlformat ...” ][“类型”]
  • 对于它的价值,我有相同的代码返回 application/vnd.openxmlformats-officedocument.wordprocessingml.documentapplication/zip 用于不同服务器上的相同文件 - 分别是 Debian 和 Centos。这使得 Laravel 对 docx 的验证在后者上失败而在前者上工作正常。所以要小心,在您部署代码的环境中进行测试。

标签: php validation docx file-type


【解决方案1】:

就我现在而言,供应商特定的文件类型 (vnd.) 未标准化(由任何 RFC),因此不包含在 file_info() 中。 .docxzipped xml-format,这就是为什么 file_info() 返回 application_zip 的原因(完全正确)。您可以解压缩文件并测试结果的 mime 类型,但这将导致文件使用的 xml(这也是完全正确的)和其他文件。要区分不同的 XML 格式 file_info() 必须分析它的内容,它必须知道它的外观,以及它的内容。

【讨论】:

  • 据我所知,除非您提取内容并检查它们,否则没有什么可以将任何 zip 文件(jar、docx、odf、zip 等)与其他文件区分开来。
  • 也许有办法将它们放入 php.ini 中?
  • 即使 php 知道 mime 类型:finfo_file() 旨在获取文件的类型,而不是其内容。明确地区分这些复杂的结构也不是那么容易。文档本身就是application/xml,所以你也需要查看和分析它。
  • @Quentin 来自我对问题的评论 - 它确实在某些情况下正确区分了类型。
【解决方案2】:

这适用于 debian。将此添加到 /etc/magic:

#------------------------------------------------------------------------------
# $File: msooxml,v 1.1 2011/01/25 18:36:19 christos Exp $
# msooxml:  file(1) magic for Microsoft Office XML
# From: Ralf Brown <ralf.brown@gmail.com>

# .docx, .pptx, and .xlsx are XML plus other files inside a ZIP
#   archive.  The first member file is normally "[Content_Types].xml".
# Since MSOOXML doesn't have anything like the uncompressed "mimetype"
#   file of ePub or OpenDocument, we'll have to scan for a filename
#   which can distinguish between the three types

# start by checking for ZIP local file header signature
0               string          PK\003\004
# make sure the first file is correct
>0x1E           string          [Content_Types].xml
# skip to the second local file header
#   since some documents include a 520-byte extra field following the file
#   header,  we need to scan for the next header
>>(18.l+49)     search/2000     PK\003\004
# now skip to the *third* local file header; again, we need to scan due to a
#   520-byte extra field following the file header
>>>&26          search/1000     PK\003\004
# and check the subdirectory name to determine which type of OOXML
#   file we have
>>>>&26         string          word/           Microsoft Word 2007+
!:mime application/msword
>>>>&26         string          ppt/            Microsoft PowerPoint 2007+
!:mime application/vnd.ms-powerpoint
>>>>&26         string          xl/             Microsoft Excel 2007+
!:mime application/vnd.ms-excel
>>>>&26         default         x               Microsoft OOXML
!:strength +10

然后,告诉 php 使用 /etc/magic 作为它的数据库:

$finfo = finfo_open(FILEINFO_MIME,"/etc/magic");

【讨论】:

  • 谢谢。我一定会测试这个!!!你认为它可以与 PHP open_basedir 一起使用吗?
  • 当我使用 .docx 文件对其进行测试并上传文件时,这对我来说非常有用。在我的本地文件系统上测试它不起作用。
【解决方案3】:

这是因为DOCX is a ZIP file:

Office Open XML 文件是与 ZIP 兼容的 OPC 包,其中包含 XML 文档和其他资源。

与 Open Office 文件一样,这些文档是 ZIP,以结构化和明确定义的方式包含各种资源。因此,当您尝试识别文件内容时,您首先会看到它是一个 ZIP 文件。然后,您需要查看 ZIP 内部以确定它是 DOCX 文件还是 OpenOffice 文件。

作为替代方案,您可以查看文件扩展名:如果您将文件识别为 ZIP 并且扩展名恰好是 .doc.docx,那么您可以假定它是 OOXML 文件。

【讨论】:

    【解决方案4】:

    在这个帖子中查看我的答案:

    概述

    PHP 使用 libmagic。当 Magic 检测到 MIME 类型为 “应用程序/zip”而不是 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 这是因为添加到 ZIP 存档的文件需要位于 一定的顺序。

    这在将文件上传到强制执行的服务时会导致问题 匹配文件扩展名和 MIME 类型。例如,基于 Mediawiki wiki(使用 PHP 编写)正在阻止某些 XLSX 文件 上传,因为它们被检测为 ZIP 文件。

    您需要做的是通过重新排序写入的文件来修复您的 XLSX 到 ZIP 存档,以便 Magic 可以正确检测 MIME 类型。

    ...

    帖子继续分析文件,并通过重写文件制定解决方案。

    这是使用 Word 创建的 DOCX 文件的文件列表。

    $ unzip -l Word.docx
    Archive:  Word.docx
      Length      Date    Time    Name
    ---------  ---------- -----   ----
         1364  1980-01-01 00:00   [Content_Types].xml
          734  1980-01-01 00:00   _rels/.rels
          817  1980-01-01 00:00   word/_rels/document.xml.rels
         1823  1980-01-01 00:00   word/document.xml
         6799  1980-01-01 00:00   word/theme/theme1.xml
         2068  1980-01-01 00:00   docProps/thumbnail.emf
         2652  1980-01-01 00:00   word/settings.xml
         1954  1980-01-01 00:00   word/fontTable.xml
          576  1980-01-01 00:00   word/webSettings.xml
          735  1980-01-01 00:00   docProps/core.xml
        28979  1980-01-01 00:00   word/styles.xml
          709  1980-01-01 00:00   docProps/app.xml
    ---------                     -------
        49210                     12 files
    

    您可能必须模仿该文件顺序或尝试先编写“[Content_Types].xml”、“word/document.xml”和“word/styles.xml”文件,然后再编写其他文件。

    【讨论】:

    • [Content_Types].xml 作为第一个归档成员是 OpenXML 的要求,还是仅仅是 libmagic 的一个缺点?
    【解决方案5】:

    我们在 PHP 5.3 中遇到了同样的问题。 它在 PHP 7.2 下运行良好。我的 docx 文件有 application/vnd.openxmlformats-officedocument.wordprocessingml.document。

    为确保您拥有 PHP 5.3 下的 docx 文件,请检查存档 (docx) 中 [Content_Types].xml 文件中的 mime 类型。

    【讨论】:

      【解决方案6】:

      在 .htaccess 中的 apache 上添加这个,以修复 docx 和所有其他文件类型问题:

      AddType application/vnd.ms-word.document.macroEnabled.12 .docm
      AddType application/vnd.openxmlformats-officedocument.wordprocessingml.document docx
      AddType application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx
      AddType application/vnd.ms-powerpoint.template.macroEnabled.12 potm
      AddType application/vnd.openxmlformats-officedocument.presentationml.template potx
      AddType application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam
      AddType application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm
      AddType application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx
      AddType application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm
      AddType application/vnd.openxmlformats-officedocument.presentationml.presentation pptx
      AddType application/vnd.ms-excel.addin.macroEnabled.12 xlam
      AddType application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb
      AddType application/vnd.ms-excel.sheet.macroEnabled.12 xlsm
      AddType application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx
      AddType application/vnd.ms-excel.template.macroEnabled.12 xltm
      AddType application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx
      

      【讨论】:

      • 请为您的答案添加一些进一步的解释。为什么 htaccess 中的这些行会修改 PHP 的 fileinfo 的行为?如果使用 nginx 或纯 CLI 应用程序,这应该如何工作?
      猜你喜欢
      • 2015-04-21
      • 1970-01-01
      • 2013-07-20
      • 2016-08-18
      • 2023-03-24
      • 2016-01-25
      • 1970-01-01
      • 2012-03-16
      • 2011-01-07
      相关资源
      最近更新 更多