2013-04-24 78 views
4

我有以下PHP代碼,顯示上傳文件的MIME類型。檢測MIME類型失敗php

<?php 

if ($_POST) { 

    var_dump($_FILES); 

    $finfo = new finfo(FILEINFO_MIME_TYPE); 

    var_dump($finfo->file($_FILES['file']['tmp_name'])); 

} else{ 
    ?> 
    <form method="POST" enctype="multipart/form-data"><input name="file" type="file"><input name="submit" value="send" type="submit"/></form> 
    <?php 
} 

用這個腳本上傳somefile.csv的結果如下。

array (size=1) 
    'file' => 
    array (size=5) 
     'name' => string 'somefile.csv' (length=12) 
     'type' => string 'text/csv' (length=8) 
     'tmp_name' => string '/tmp/phpKiwqtu' (length=14) 
     'error' => int 0 
     'size' => int 3561 
string 'text/x-fortran' (length=14) 

所以當然MIME類型應該是文本/ csv。但是我使用的框架(Symfony 1.4)使用fileinfo方法。

而且我測試遠一點似乎file --mime-type somefile.csv返回somefile.csv: text/x-fortran命令(在Ubuntu)和命令mimetype somefile.csv返回somefile.csv: text/csv。 somefile.csv是用MSOffice創建的(我不知道這是否重要)。 顯然mimetype使用了一些很棒的mime數據庫(http://freedesktop.org/wiki/Software/shared-mime-info),而file沒有。

  1. PHP是否使用filemimetype或兩者皆不?
  2. 此外,我不確定這裏要做什麼;我上傳的文件格式錯誤?我必須使用不同的mime數據庫嗎? PHP是否被竊聽?這裏發生了什麼?

編輯:

爲什麼它被檢測爲Fortran程序的原因是因爲somefile.csv只包含以下內容:

somecolumn; 
C F; 

相信的上述內容CSV文件有效嗎?如果一個字段包含空格,則該字段不必放在引號內,對嗎?

回答

0

PHP Mimetype introduction

本擴展已被棄用在一個更清潔的方式PECL擴展Fileinfo的提供相同的功能(和更多)。

該模塊中的函數嘗試通過在文件中的特定位置查找某些魔術字節序列來猜測文件的內容類型和編碼。雖然這不是一個防彈的方法,但所使用的啓發式方法做得非常好。

此擴展名來自Apache mod_mime_magic,它本身是基於由Ian F. Darwin維護的文件命令。查看源代碼以獲取更多歷史和版權信息。

PHP Fileinfo introduction

此模塊中的功能,試圖通過尋找在文件中的特定位置的某些魔術字節序列來猜測文件的內容類型和編碼。 雖然這不是防彈的方法,但所用的啓發式方法做得很好

下面是關於同一主題的一些答案的問題:Detecting MIME type in PHP

+0

http://pear.php.net/package/MIME_Type給出了相同的結果als file_info。我不明白爲什麼一個CSV文件看起來像一個fortran文件。 – meijuh 2013-04-24 11:57:30

+0

看看Fortran代碼示例,我無法弄清楚爲什麼發生這種情況,它們完全不同。 如果您在簡單的文本編輯器中打開該特定的CSV文件,它看起來像純CSV還是其他元素可能導致混淆結果? – 2013-04-24 13:15:10

+0

另外5美分,我搜索了很好的基於PHP的網絡應用程序,這裏有其他方法:Drupal 8似乎使用Guzzle PHP框架來完成這項工作,在https://github.com/guzzle/guzzle上查看他們的代碼。 /blob/master/src/Guzzle/Http/Mimetypes.php。 他們只是對預先定義的已知MIME類型列表進行簡單的擴展檢查。不是我要說的。 – 2013-04-24 13:21:13

5

我沒有Unix機器在這裏考察一個真正的「神奇」的文件(用來猜測MIME類型庫),但快速谷歌搜索發現這一點:

# $File: fortran,v 1.6 2009/09/19 16:28:09 christos Exp $ 
# FORTRAN source 
0  regex/100  \^[Cc][\ \t] FORTRAN program 
!:mime text/x-fortran 

顯然,它會掃描該文件的開頭尋找以單個C字母加空格開頭的行,這些行似乎是Fortran style comment。因此,誤報:

somecolumn; 
C F; 
+0

因此,我應該如何處理誤報?我知道解決方案是在每個單元格周圍加引號,但這並不是我想要的,因爲我的web應用程序的用戶上載了這些CSV文件,並且示例顯示的是一個有效的CSV文件 – meijuh 2013-04-24 15:47:10

+0

In取決於您的確切需求,但是,在這種情況下,最好使用文件擴展名。你也可以爲你的mime文件移除Fortran。 (不知道爲什麼你在這裏使用啓發式,如果你已經知道它是CSV;猜測MIME類型將不驗證文件) – 2013-04-24 15:49:21

+0

那麼CSV文件是由應用程序的用戶上傳。如果誤報是猜測MIME類型的結果,那麼使用MIME類型猜測沒有任何意義。我只會確保該文件在公用文件夾中不可執行,用戶應該知道他們正在下載的內容。此外,由於我僅使用CSV文件,並且CSV文件的語法必須正確,所以我還可以使用BNF語法檢查CSV文件的內容。 – meijuh 2013-04-24 18:00:04