ユーザがブラウザからファイルをアップロードした際に、サーバでファイルタイプをチェックする方法。
おおまかに、ブラウザの環境変数から検証する方法と、サーバ側でチェックする方法がある。
簡単にチェック
まず、$_FILES変数にファイルタイプが設定されているのでこれを使う例。
typeというキーに入っています。
print_r($_FILES); Array ( [file] => Array ( [name] => site-csv-200902261653.csv [type] => text/comma-separated-values [tmp_name] => /tmp/phpMaX6wO [error] => 0 [size] => 3604 ) )
しかしながら、ブラウザによってこの値は異なります。(Windows VistaでCSVファイルをアップロードして検証)
Chromeに至っては、null。。。。
- FF3:text/comma-separated-values
- IE7:application/octet-stream
- Opera: text/comma-separated-values
- safari: application/octet-stream
- chrome: null
type変数を信じる場合は、メジャーなブラウザの場合は以下のコードで検証できます。これは、ブラウザ出力を信頼する場合。
$valid_type = array('text/comma-separated-values','application/octet-stream',null); if(in_array($_FILES['file']['type'], $valid_type){ print 'valid'; }else{ print 'invalid'; }
しっかりチェック
サーバ側でちゃんとやるためには、Fileinfoライブラリを使う。
FileinfoはPECLで提供されている。libmagicライブラリに依存している。
# aptitude install libmagic-dev # pecl install fileinfo
php.iniに以下を追加して、サーバ再起動。
extension='fileinfo.so'
以下のように書けば、ファイルタイプを返してくれる。
$finfo = finfo_open(FILEINFO_MIME); echo finfo_file($finfo, $csv_file) . "\n"; finfo_close($finfo);
text/plain charset=unknown
判定は以下のように。
$finfo = finfo_open(FILEINFO_MIME); $type = finfo_file($finfo, $csv_file) ; finfo_close($finfo); if(strpos($type, 'text/plain') !== false){ print 'valid'; }
Comments