[PHP]header()のContent-TypeにおけるMIME Typeの種類などのまとめ

Read More

PHPではファイル出力の際、header()のContent-Typeを使ってファイルの種類をヘッダー情報として付与することができる。
このContent-Type、割と使う機会が多いわりにそのMIME Typeを今までちゃんとまとめたことがなかった。

そこで自分が過去使ったもの中心に書き出しておくこととする。

またContent-Typeだけでなくファイル出力におけるその他の必要情報も合わせて載せておく。
ページ末尾にはいくつかの実用サンプルも載せておく。


なおLocationやRefresh、HTTP/1.0などについてはいずれ別でまとめるものとしここでは触れない。



header()のContent-TypeにおけるMIME Typeの種類

■Content-TypeにおけるMIME Typeの種類
・テキスト
header('Content-Type: text/plain');
・HTML
header('Content-Type: text/html; charset=Shift_JIS');
・XHTML
header('Content-Type: application/xhtml+xml; charset=UTF-8');
・JSON
header('Content-Type: application/json; charset=UTF-8');

・CSV(コンテンツタイプが不明の場合もこれ)
header('Content-Type: application/octet-stream');
・PDF
header('Content-Type: application/pdf');
・RSS
header('Content-Type: text/xml);
header('Content-Type: application/xml');
・JS
header('Content-Type: application/x-javascript');
・CSS
header('Content-Type: text/css');
・Images
header('Content-Type: image/gif');
header('Content-Type: image/jpeg');
header('Content-Type: image/png');

補足:Imagesにはimage_type_to_mime_type()と定数を組み合わせた記述も可能
header('Content-Type: '. image_type_to_mime_type(IMAGETYPE_PNG));

IMAGE_XXX定数には以下のようなものがある。
IMAGETYPE_GIF
IMAGETYPE_JPEG
IMAGETYPE_PNG
ttp://php.net/manual/ja/function.image-type-to-mime-type.php#refsect1-function.image-type-to-mime-type-returnvalues


以下は注意点。
・'Content-type'ではなく'Content-Type'が正しい。間違っていても動くが。
・MIME Charsetを指定する場合はMIME Typeの後ろに区切り文字として";"(セミコロン)を付ける。半角空白を忘れないこと。
・MIME Charsetの代入演算子は"="(イコール)である。":"(コロン)ではない。
・MIME Charsetを指定にはできればmb_preferred_mime_name()を使った方が良い。
 なぜならSJIS-winという指定などはPHP独自のものであるから。
 これは引数にSJIS-winと指定するとShift_JISという文字列が返ってくる。
・RSSファイルはapplication/rdf+xmlとは指定しない。一部のブラウザで正しく処理されない可能性がある。



ファイルの性質を指定する

ファイルの性質はアタッチメント(添付ファイル)とインライン(画面組み込み)の2通りが指定できる。
ファイルをダウンロードする場合はアタッチメント、画面表示の場合はインラインを指定する。

■ファイルの性質を指定:ダウンロード
header('Content-Disposition: attachment; filename="'.$filename.'"');

$filenameには"example.csv"などの任意のファイル名を入れる。


こちらはダウンロードと対の機能となる画面出力の記述。
■ファイルの性質を指定:画面表示
header('Content-Disposition: inline; filename="'.$filename.'"');

$filenameには"example.jpg"などの任意のファイル名を入れる。




ファイルの長さ(ファイルサイズ)

ブラウザによってはlengthを出力してやらないとDLが途中で止まることがある。
特にファイルサイズが大きなもの、時間がかかるようなものはその症状が出やすい。
なおブラウザによってはこれを書いておくことでプログレスバーが表示されるようになる。

■ファイルの長さ(ファイルサイズ)
header('Content-Length: '.$length);

$lengthはバイト数。


■動的なファイル生成におけるバイト数の取得例
<?php
ob_start();
// ここで出力処理
$length = ob_get_length();
print $length;
?>



■動的なファイル生成におけるバイト数の取得例_その2
<?php
ob_start();
// ここで出力処理
$contents = ob_get_contents();
ob_end_clean();
$length = strlen(bin2hex($contents))/2;
print $length;
?>



■静的なファイル指定におけるバイト数の取得例
<?php
$length = filesize($filepath);
print $length;
?>

$filepathには任意のファイルパスを入れる。
補足:PHP の数値型は符号付整数であり、 多くのプラットフォームでは 32 ビットの整数を取るため、 ファイルシステム関数の中には 2GB より大きなファイルについては期待とは違う値を返すものがある。

filesize()のほかにもCURL関数を使ったものも存在する。




総括
ファイル出力では、
Content-Type、Content-Disposition、Content-Lengthはセットで書く
ようにすること。

他にもファイル出力時においてCache-Control、Pragma、Last-Modified、Expiresなど指定する場合があるがこれらは別に必須というわけでもない。
そしてこれらはブラウザによって挙動の差異も大きかったりして結構思う通りにならなかったりする(と、うろ覚えの記憶にある)。

ファイル出力においてはサイト(システム)の性質とその製作コストとを考え使い分けたい。
まあいずれ機会があれば調べなおすこともあろう。




-- ↓ここからは実用サンプル --




■DLできるファイル出力の例
<?php
header('Content-Type: application/octet-stream'); // コンテンツの種類
header('Content-Disposition: attachment; filename="dl.zip"'); // ダウンロードするファイル名
header('Content-Length: '.filesize('dl.zip')); // ファイルサイズを指定を忘れない
readfile("dl.zip"); // コンテンツの内容をファイルから読み込んでそのまま出力
exit;
?>



■RSSファイル出力の例
<?php
ob_start();
?><?php print'<?xml version="1.0" encoding="UTF-8"?>'.PHP_EOL;?>
<rss version="2.0">
-- RSS生成 --
</rss>
<?php
$length = ob_get_length();
header('Content-Type: text/xml; charset=UTF-8'); // コンテンツの種類
header('Content-Disposition: inline; filename="index.rss"');
header('Content-Length: '.$length)); // ファイルサイズを指定
exit;
?>



■PDFファイルを画面表示出力する例
<?php
$pdf = PDF_new();
// ここでPDF生成
$contents = PDF_get_buffer($pdf);
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="'.$filename.'"');
header('Content-Length: '. strlen(bin2hex($contents))/2);
header('Cache-Control: public');
header('Pragma: public');
print $contents;
exit;
?>



■画像ファイルを画面表示出力する例
<?php
$filepath = '{画像ファイルパス}';
$image_type_index = exif_imagetype($filepath);
$contents = file_get_contents($filepath);
$length = strlen(bin2hex($contents))/2;
$filename = basename($filepath);
header('Content-Type: '.image_type_to_mime_type($image_type_index));
header('Content-Disposition: inline; filename="'.$filename.'"');
header('Content-Length: '.$length);
print $contents;
exit;
?>





-- 2018/03/22 追記: Content-TypeにJSON形式のものを追加







Comments(1)

1  115ちゃん  2013/07/29 (月) 16:10 ID:ta4ZbyB15
わ~~~!今ちょうど添付ファイルありのメールを送るのやってて、
ほうほうと見させてもらいました。
画像添付ファイルの時と、本文中に画像を表示する時の違いや注意点とかありますか??