MIMEタイプ
PHPでファイルのMIMEタイプを取得するには、
$mime = mime_content_type($file['tmp_name'][0]);
形式はtype/subtype
です。例えばmp3の場合、代表的なMIMEタイプはaudio/mpeg
ですが、独自拡張のaudio/mp3
やaudio/x-mpeg
等を含めるために、これらのmpegやmp3を$subtype
と置くと、
$bool = preg_match('/^audio.*'.$subtype.'$/',$mime);
この関数は第1引数で指定したパターンが第2引数に含まれているかどうかを真偽で返します。第1引数の/
で囲まれる文字列には正規表現を指定します。^
は文頭を、$
は文末を、.
は任意の文字を、*
は直前の文字の0個以上の繰り返しを意味します。この.*
の指定によって、x-
という接頭辞の有無によらず判定をしています。
Application/octet-stream
このmp3に関してなのですが、正確な判別がされずに、未知のMIMEタイプとしてapplication/octet-stream
を返すことがありました。PHPの関数だけでなくLinuxのコマンドであるfile
で調べても同様だったので、Super Userを参考にして、/etc/magic
のファイルに以下の一文を追加しました。
# MPEG Layer 3 sound files
0 beshort &0xffe0 audio/mpeg
!:mime audio/mpeg
#MP3 with ID3 tag
0 string ID3 audio/mpeg
!:mime audio/mpeg
これにより、Linuxのコマンドfile
を用いると
file -bi town.mp3
オプションについて、b
はファイル名の出力を省略し、i
はMIMEタイプ形式で出力します。この結果は以下のようになります。
$ file -bi town.mp3 audio/mpeg; charset=binary
この出力を取得するために、上記のコマンドを$command
と置き、PHPのexec()
を用いると、
exec($command.' </dev/null 2>&1',$contentAry,$error);
2>&1
の指定によって、標準エラー出力は標準出力と同じ出力にリダイレクトされ、その結果は$contentAry
に格納されます。第3引数の$error
には、コマンド成功時には0が、失敗時には1が入ります。
次に、この出力から特定の文字列を抜き出します。
preg_match('/^(.*); charset/',$contentAry[0],$mimeAry);
第1引数のパターン内に()
を指定して、パターンが第2引数にマッチした際に、その括弧の中の文字列を、第3引数である$mimeAry
に渡します。この第3引数は配列形式で、$mimeAry[0]
にはマッチしたパターン全体が、$mimeAry[1]
には括弧で指定した文字列が格納されるので、
$mime = $mimeAry[1];
として、目的の文字列audio/mpeg
を取り出します。
以上が、今のサイトの仕様なのですが、音楽素材として配布されている中には、m4aであればMIMEタイプがvideo/mp4
といったものもあります。上記の方法よりも、FFmpegにおいてファイルを解析する機能であるFFprobeを使って調べるなど、他の方法を検討する余地があります。
URL: sac.ringil-music.com
環境: さくらのVPS・Centos7・Nginx・PHP-FPM