PHP で csv をダウンロードさせたくなったので作りました。なお、一時ファイル作成しない方向での構成です。
構成
構成としては、
form
タグ 内にダウンロードボタンを設けた最初のページ- 実際にデータから 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 がダウンロードできることを確認しました。