HOME


PHPのちょっとしたTIPS

Last Modified : 2003/03/18 (Tue)
No.5 任意のファイルをダウンロードさせる - readfile()

PHPスクリプトにアクセスした時にブラウザにダウンロードダイアログを開かせて、サーバ上の任意のファイルをダウンロードできるようにします。
特に難しい部分はありません。HTTPヘッダがいつも使うのと違うだけです。
とりあえずサンプルを。
<?php
/*
    引数はターゲットファイルへの相対又は絶対パス
*/
function download_file($path_file)
{
    /* ファイルの存在確認 */
    if (!file_exists($path_file)) {
        die("Error: File(".$path_file.") does not exist");
    }

    /* オープンできるか確認 */
    if (!($fp = fopen($path_file, "r"))) {
        die("Error: Cannot open the file(".$path_file.")");
    }
    fclose($fp);

    /* ファイルサイズの確認 */
    if (($content_length = filesize($path_file)) == 0) {
        die("Error: File size is 0.(".$path_file.")");
    }

    /* ダウンロード用のHTTPヘッダ送信 */
    header("Content-Disposition: inline; filename=\"".basename($path_file)."\"");
    header("Content-Length: ".$content_length);
    header("Content-Type: application/octet-stream");

    /* ファイルを読んで出力 */
    if (!readfile($path_file)) {
        die("Cannot read the file(".$path_file.")");
    }
}
?>
HTTPヘッダを3つ出力しています。

1. Content-Disposition: inline; filename="ファイル名"
2. Content-Length: データサイズ
3. Content-Type: application/octet-stream

各ヘッダの働きとしては、

1. ブラウザにファイル名を教えてあげます。このファイル名がダウンロードダイアログに現れるはずです。
2. ダウンロードするファイルのサイズをブラウザに教えてあげます。これでプログレスバーが動きます。
3. application/octet-stream を指定することでブラウザがダウンロードダイアログを開いてくれます。

詳しくはRFCを参照して下さい。

で、あとはreadfile()でファイルをそのまま出力してあげるだけです。

ファイルをダウンロードさせる方法としてはLocationヘッダで目的のファイルへのURLを指定して飛んでもらってもいいのですが、それだとブラウザで直接参照できるファイルしかダウンロードできません。
しかし上の方法だと、サーバ上でPHPの実行権限で読めるファイルは全部ダウンロードできます。そういう場合にはとても便利ですね。
その半面、QUERY_STRINGでファイルのパスを指定するようにしてほったらかしにしたりすると危険ですので注意が必要です。