PHP で csv をダウンロードするボタンを作る

PHP で csv をダウンロードさせたくなったので作りました。なお、一時ファイル作成しない方向での構成です。

構成

構成としては、

  1. formタグ 内にダウンロードボタンを設けた最初のページ
  2. 実際にデータから csv を生成してダウンロードさせる処理を走らせるページ

の二段構えで作成します。

1.formタグ 内にダウンロードボタンを設けた最初のページ

まずはダウンロードボタンのフォームです。

    <?php session_start(); ?>
    <form action="./download.php" method='post' class="py-4">
        <input name="token"  type="hidden" value="<?php echo htmlspecialchars(session_id(), ENT_COMPAT, 'UTF-8'); ?>" />
        <button type="submit" class="btn btn-primary"><i class="fa-solid fa-fw fa-file-csv" aria-hidden="true"></i>csvダウンロード</button>
    </form>

一応 CSRFトークン 付きにしています。

2.実際にデータから csv を生成してダウンロードさせる処理を走らせるページ

<?php

date_default_timezone_set('Asia/Tokyo');
mb_language('ja');
mb_internal_encoding('UTF-8');

// CSRF対策
if(!isset($_POST['token']) || empty($_POST['token'])) {
    echo 'トークンがありません。不正な処理です。';
    exit();
}
session_start();
if(session_id() !==  $_POST['token']){
    echo 'トークンが一致しません。不正な処理です。';
    exit();
}

// この辺りでデータを用意

$file_path = 'hoge.csv';

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename*=UTF-8\'\'' . rawurlencode($file_path));

$fp = fopen('php://output', 'w');
foreach($rows as $val) {
    fputcsv($fp, $val, ',', '"', '\\');
}
fclose($fp);

exit();
サンプルのcsvをダウンロードして開いてみた
サンプルのcsvをダウンロードして開いてみた

これで csv がダウンロードできることを確認しました。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。