【これだけ】PHPでファイルをダウンロードさせる方法【現役エンジニアが解説】

PROGRAM

今回は、PHPでファイルをダウンロードさせる方法について、新規ファイルと既存ファイルの場合に分け、簡単に解説していきます。

新規でファイルを作成しダウンロードさせる方法

新規でファイルを作成しダウンロードさせる場合は、fopen関数を使います。

$filename = "hoge.csv"; // CSVファイルの名前
$filedata = array(); // 連想配列の配列や配列の配列
header("Content-Type: application/octet-stream; charset=utf-8");
header("Content-Disposition: attachment; filename=".$filename."; filename*=UTF-8''".rawurlencode($filename));
$file = fopen('php://output', "w" );
// fwrite($file, "\xEF\xBB\xBF"); // BOM付きにさせる場合にファイルの先頭に書き込む
foreach($filedata as $row) {
    fputcsv($file, $row); // 配列の各要素をCSVにしていく
}
fclose($file);

上記のコードはPHPで持っているデータをCSVファイルに出力するコードです。

header関数でContent-Typeを指定することによって、ブラウザを通してダウンロードさせることができます。

既存のファイルをダウンロードさせる方法

既存のファイルをダウンロードさせる場合もfopen関数を使います。

$filename = "hoge.zip"; // ダウンロード時のファイル名
$filepath = "{file_path}"; // ダウンロードさせるファイルのパス
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename=".$filename.";  filename*=UTF-8''".rawurlencode($filename));
header('Content-Length: ' . filesize($filepath));

while (ob_get_level() > 0) {
    ob_end_clean();
}
ob_start();

if ($file = fopen($filepath, 'rb')) {
    while(!feof($file) and (connection_status() == 0)) {
        echo fread($file, '4096');
        ob_flush();
    }
    ob_flush();
    fclose($file);
}
ob_end_clean();

上記コードはWebサーバに置いてあるzipファイルをブラウザを通してダウンロードさせるコードです。

このコードでは、巨大なファイルでもメモリオーバにならないように細かく区切りながら出力するコードとなっています。

ダウンロードできない場合

これらのコードを使っても、ダウンロードできない場合があります。

ini_set("memory_limit","128M");

新規でファイルを作成しダウンロードさせる際に失敗する場合は、上記のようにini_set関数でメモリの上限値を変えて、増やしましょう。

ini_set("max_execution_time",0);

一方で、新規でも既存でも巨大なファイルのダウンロードで失敗してしまうような場合には、上記のようにini_set関数を使って、phpの処理時間を無制限にします。