2024 年日本 PHP 研討會

檔案資訊函式

目錄

新增註記

使用者貢獻的註記 13 則註記

Paul
17 年前
這個函式的結果似乎不太可靠。

例如:
1) 一個 Word 文件會返回
'application/msword application/msword'
...還不錯,但為什麼會返回兩次?

2) 一個 PHP 檔案會返回
'text/x-c++; charset=us-ascii'
我的測試檔案是以 '<?php' 開頭,所以應該很明確。它是從哪裡得到字元集的假設?

3) 一個以字母 'GIF' 開頭的文字文件會返回
'image/gif'
(就像 DanielWalker 在 unix 'file' 命令的範例中一樣)

我使用 PEAR 的 'MIME_Type' 套件得到更好的結果。它對 1 和 3 提供了正確的答案,並將 PHP 檔案識別為 'text/plain',這可能比錯誤匹配 C++ 更好。

finfo_file 和 MIME_Type 都正確識別了我的另外兩個測試檔案,一個是副檔名改為 .doc 的 Windows exe 檔案,另一個是副檔名也改為 .doc 的 PDF 檔案。
ccbsschucko at gmail dot com
6 年前
<?php
class FileInfoTool {

/**
* @var str => $file = caminho para o arquivo (ABSOLUTO OU RELATIVO)
* @var arr => $file_info = array contendo as informações obtidas do arquivo informado
*/
private $file;
private
$file_info;

/**
* @param str => $file = caminho para o arquivo (ABSOLUTO OU RELATIVO)
*/
public function get_file(string $file){
clearstatcache();
$file = str_replace(array('/', '\\'), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file);
if(!
is_file($file) && !is_executable($file) && !is_readable($file)){
throw new
\Exception('O arquivo informado não foi encontrado!');
}
$this->file = $file;
$this->set_file_info($this->file);
return
$this;
}

/**
* @param str => $index = se for informado um indice é retornada uma informação específica do arquivo
*/
public function get_info($index = ''){
if(
$this->get_file_is_called()){
if(
$index === ''){
return
$this->file_info;
}
if(
$index != ''){
if(!
array_key_exists($index, $this->file_info)){
throw new
\Exception('A informação requisitada não foi encontrada!');
}
return
$this->file_info;
}
}
}

/**
* @todo verifica se o método get_file() foi utilizado para informar o caminho do arquivo
*/
private function get_file_is_called(){
if(!
$this->file){
throw new
\Exception('Nenhum arquivo foi fornecido para análise. Utilize o método get_file() para isso!');
return
false;
}
return
true;
}

/**
* @todo preencher a array com as infos do arquivo
*/
private function set_file_info(){
$this->file_info = array();
$pathinfo = pathinfo($this->file);
$stat = stat($this->file);
$this->file_info['realpath'] = realpath($this->file);
$this->file_info['dirname'] = $pathinfo['dirname'];
$this->file_info['basename'] = $pathinfo['basename'];
$this->file_info['filename'] = $pathinfo['filename'];
$this->file_info['extension'] = $pathinfo['extension'];
$this->file_info['mime'] = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $this->file);
$this->file_info['encoding'] = finfo_file(finfo_open(FILEINFO_MIME_ENCODING), $this->file);
$this->file_info['size'] = $stat[7];
$this->file_info['size_string'] = $this->format_bytes($stat[7]);
$this->file_info['atime'] = $stat[8];
$this->file_info['mtime'] = $stat[9];
$this->file_info['permission'] = substr(sprintf('%o', fileperms($this->file)), -4);
$this->file_info['fileowner'] = getenv('USERNAME');
}

/**
* @param int => $size = valor em bytes a ser formatado
*/
private function format_bytes(int $size){
$base = log($size, 1024);
$suffixes = array('', 'KB', 'MB', 'GB', 'TB');
return
round(pow(1024, $base-floor($base)), 2).''.$suffixes[floor($base)];
}
}

var_dump((new FileInfoTool)->get_file('sitemap.xml')->get_info());
?>
jon at cybus dot co dot uk
17 年前
為了讓 v1.0.4 在我的 Ubuntu Feisty 系統上運作,我必須執行以下操作。在 Debian 上可能也一樣。

* apt-get install libmagic1-dev
* pecl install Fileinfo
* 將 "extension=fileinfo.so" 添加到 php.ini (/etc/php5/{cli,cgi}/php.ini)
* ln -s /usr/share/file/magic /etc/magic.mime
Terren Suydam
16 年前
如果 finfo_file() 返回的 MIME 類型也包含字元集定義(以分號分隔),例如

text/plain; charset=us-ascii

那麼您可能需要將字元集定義保留在 MIME 類型中,尤其是在 HTTP Content-Length 標頭中使用結果字串時。HTTP 標準明確允許這樣做,請參閱

http://www.w3.org/International/O-HTTP-charset

之前的某些評論者似乎試圖移除字元集。
Evermorian
16 年前
回應下方 "jon at cybus" 建議將 /usr/share/file/magic 符號連結到 /etc/magic.mime 的建議,請注意,這會導致其他問題(至少在 Debian Etch 中是如此)。它會破壞 file 命令的 -i 功能,使其返回人類可讀的字串而不是 MIME 類型。它也會導致 finfo 做同樣的事情。

因此,在實例化 finfo 物件時,最好正確指定 magic 檔案的路徑

<?php
$fi
= new finfo(FILEINFO_MIME,'/usr/share/file/magic');
$mime_type = $fi->buffer(file_get_contents($file));
?>

當然,最終你得到的東西仍然無法區分 Word 文件和 Excel 試算表。
szotsaki at gmail dot com
17 年前
我正要寫我是如何安裝這個套件的。

首先,我按照手冊說明,嘗試使用「pear install fileinfo」。
但 pear 命令顯示「套件 “Fileinfo” 無效,
安裝失敗」。

接著,使用「pear install pecl/fileinfo」是比較好的方法。但當時缺少「phpize」命令。
我安裝了它(在 openSUSE 發行版中,它位於 php5-devel 套件中,但我認為你可以在你發行版對應的 php-devel 套件中找到它)。

之後,你可能需要安裝「re2c」(我有安裝)。它的首頁是:http://sourceforge.net/projects/re2c

將 Apache 的 magic 檔案(通常位於 /etc/apache2 中)複製到以下目錄:/usr/locale/share/file/ 或 /usr/share/file/

然後你必須安裝「libmagic-dev」。如果你使用的是基於 Debian 的系統,你可以直接使用 apt 安裝它。
但如果你使用的是基於 rpm 的系統(像我一樣),你必須下載以下套件:http://packages.debian.org/unstable/libdevel/libmagic-dev
它包含我們需要的檔案。
所以,下載檔案,使用 Midnight Commander (mc) 瀏覽它(你必須安裝 apt 和 dpkg),然後將 .deb 套件的 /usr 資料夾(它位於 CONTENTS 資料夾內)解壓縮(也就是複製)到根目錄。

現在再次嘗試執行「pear install pecl/fileinfo」命令 :)

附註:別忘了檢查腳本是否已將以下行寫入 php.ini(在 openSUSE 上:/etc/php5/apache2):extension=fileinfo.so

希望我能幫上忙。
aidan at php dot net
17 年前
PHP 警告:finfo::finfo():無法載入位於「/etc/magic」的 magic 資料庫
PHP 警告:finfo::file():無效的 fileinfo 物件

可以透過將 magic 資料庫(根據你的發行版,這個檔案可能位於任何位置,在 Debian 上它位於 /usr/share/file/magic)複製到 /etc/magic.mime 來修正這些錯誤。

libmagic 會自動將 .mime 附加到檔名末尾,因此 PHP 錯誤地報告了它正在尋找的路徑。

同樣適用於
PHP 警告:finfo::finfo():無法載入位於「/etc/magic.mime」的 magic 資料庫

遺憾的是,在這種情況下,使用者必須將 magic 檔案命名為 /etc/magic.mime.mime。
jausions at php dot net
18 年前
適用於 Windows 使用者

1. 如果你的 PHP 安裝版本沒有 php_fileinfo.dll,而且你沒有安裝 Extensions 套件,請前往 http://pecl4win.php.net/ 取得 php_fileinfo.dll。

2. 然後確保你的 php.ini 中的某處有 extension=php_fileinfo.dll。

3. 重新啟動你的網頁伺服器。
aidan at php dot net
15 年前
從 PHP 5.3 開始,Fileinfo 隨主要發行版一起提供,並且預設啟用。此擴充功能不再在 PECL 中維護。
motin at demomusic dot nu
17 年前
我嘗試透過 pear/pecl 安裝這個套件時遇到了很大的麻煩。遇到了看起來像這個錯誤的問題:http://pecl.php.net/bugs/bug.php?id=7673 (phpize 失敗)

我發現手動下載套件並執行 ./configure 有助於顯示問題所在

...
檢查 fileinfo 支援... 是,已分享
檢查預設路徑中的 magic 檔案... 未找到
設定:錯誤:請重新安裝 libmagic 發行版
<quit>

我原本以為這是因為缺少了類似 magic.mime 的魔法資料庫,但檢查 configure 設定檔後,發現它搜尋的是 magic.h。

我的問題是找不到 include/magic.h。在 Google 上搜尋 magic.h 的位置後,卻發現…
簡單的解決方案

apt-get install libmagic-dev

奇怪的是,這並 *沒有* 解決原本的安裝錯誤,但允許手動安裝。

1. 從 http://pecl.php.net/package/Fileinfo 找到 Fileinfo 最新版本的網址 (目前是:http://pecl.php.net/get/Fileinfo-1.0.4.tgz)

2. 下載、編譯和安裝
wget http://pecl.php.net/get/Fileinfo-1.0.4.tgz
gunzip Fileinfo-1.0.4.tgz
tar -xvf Fileinfo-1.0.4.tar
cd fileinfo-1.0.4
./configure
make
make install

3. 在你的 php.ini 檔案中加入 extension=fileinfo.so

4. 重新啟動 Apache
Alexey
17 年前
嗯,安裝和使用這個擴充功能很困難。有一個更好的替代方案 - 使用 Linux 指令 "file"。使用方法請在 Linux shell 中輸入 "man file"。

<?
echo system("file -i -b file.pdf");
?>

application/pdf
bostjan at a2o dot si
14 年前
「無法載入魔法資料庫於...」

這個錯誤訊息可能是程式庫和資料庫不相容造成的。使用 file 指令編譯資料庫來檢查,如下所示:

cd /etc/magic
file -C -m magic
file -C -m magic.mime

b.
nessi at nessi dot ch
14 年前
對於 openSUSE 來說,你只需要安裝 file-devel 即可解決這個問題:
檢查預設路徑中的 magic 檔案... 未找到
設定:錯誤:請重新安裝 libmagic 發行版

zypper install file-devel
To Top