PHPプログラミング

ワークショップ

ひと言掲示板を作る

投稿データをCSV形式でダウンロードする

「ひと言掲示板」の管理ページについて、投稿データをCSV形式でダウンロードする機能を実装します。

この記事のポイント

  • ファイル出力はheader関数で指定する
  • ページとして表示しないときはreturnでPHPを終了させる

目次

投稿データをCSV形式でダウンロードする

前回はひと言掲示板の管理ページについて、運営者がログインする機能を実装しました。
今回は管理ページに投稿データをダウンロードする機能を実装していきます。

投稿データをCSV形式でダウンロードできるようになりますが、大まかな流れは次のようになります。

投稿データをダウンロードするまでの流れ

admin.php」が「download.php」を呼び出して、「download.php」でCSVファイルを作成、そして最後に作成したファイルをダウンロードの形で出力して終了します。

「ひと言掲示板を作る」の概要については「ひと言掲示板を作る」をご覧ください。
デモはこちら

前回までに作成したコードはこちら:Github

管理ページにダウンロードボタンを設置する

まずは管理ページの「admin.php」に「download.php」を呼び出すためのボタンを設置しましょう。
上記の1番にある「呼び出す」の部分です。
次のようにform要素を追記してください。

コード例


-- 省略 --

<body>
<h1>ひと言掲示板 管理ページ</h1>
<?php if( !empty($error_message) ): ?>
    <ul class="error_message">
		<?php foreach( $error_message as $value ): ?>
            <li>・<?php echo $value; ?></li>
		<?php endforeach; ?>
    </ul>
<?php endif; ?>
<section>
<?php if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ): ?>

<form method="get" action="./download.php">
    <input type="submit" name="btn_download" value="ダウンロード">
</form>

<?php if( !empty($message_array) ){ ?>
<?php foreach( $message_array as $value ){ ?>
<article>
    <div class="info">
        <h2><?php echo $value['view_name']; ?></h2>
        <time><?php echo date('Y年m月d日 H:i', strtotime($value['post_date'])); ?></time>
    </div>
    <p><?php echo $value['message']; ?></p>
</article>
<?php } ?>
<?php } ?>

-- 省略 --

「ダウンロード」ボタンが押されると、form要素action属性で指定しているdownload.phpが呼び出されます。
また、今回はログイン情報のような大事なパラメータの受け渡しはありませんのでGET形式にしています。

ダウンロードボタンが表示される

download.phpを作成する

続いて、呼び出される「download.php」を作成します。
いきなりファイル作成や出力する処理は書かずに、まずは初期設定する内容だけを記述して「download.php」という名前でファイルを作成してください。

コード例

<?php

// データベースの接続情報
define( 'DB_HOST', 'localhost');
define( 'DB_USER', 'root');
define( 'DB_PASS', 'password');
define( 'DB_NAME', 'board');

// 変数の初期化
$csv_data = null;
$sql = null;
$res = null;
$message_array = array();

session_start();

if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ) {

	// ここにファイル作成&出力する処理が入る

} else {

	// ログインページへリダイレクト
	header("Location: ./admin.php");
}

return;

admin.php」と同様に、データベースへの接続情報は定数として宣言します。
その後に、あとで使う変数の初期化が並びます。

その後には管理ページと同じようにsession_start関数とif文によるログインセッションの確認が入ります。
ここで、ダウンロードを実行するユーザーが運営者なのかを判断し、もしそうであればファイルを作成する処理を実行するという内容になっていきます。

もし運営者以外のユーザーによるアクセスだった場合は、header関数を使って「admin.php」に移動するようにしています。
ログインセッションがないまま管理ページに移動するので、結果としてはログインページが表示されます。

最後に、「download.php」はページを表示しないため明示的にreturn;を記述しています。

CSV形式のファイルを作成する

引き続き「download.php」にCSV形式のファイルを作成するコードを記述していきましょう。

コード例

<?php

-- 省略 --

if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ) {

	// 出力の設定
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=メッセージデータ.csv");
	header("Content-Transfer-Encoding: binary");

} else {

-- 省略 --

return;

3つのheader関数を追記しました。
これは全てPHPの出力形式として、「Content-Type」「ファイル名」「エンコーディング」を順に指定しています。
2つ目の「ファイル名」は実際にダウンロードされるファイル名になります。

続いて、データベースから投稿データを取得するコードを追記します。

コード例

<?php

-- 省略 --

if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ) {

	// 出力の設定
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=メッセージデータ.csv");
	header("Content-Transfer-Encoding: binary");

	// データベースに接続
	$mysqli = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME);
	
	// 接続エラーの確認
	if( !$mysqli->connect_errno ) {

		$sql = "SELECT * FROM message ORDER BY post_date ASC";
		$res = $mysqli->query($sql);

		if( $res ) {
			$message_array = $res->fetch_all(MYSQLI_ASSOC);
		}

		$mysqli->close();
	}

} else {

-- 省略 --

return;

データを取得して$message_arrayに代入していますが、ここは管理ページと共通です。

続いて、取得したデータからCSVファイルを作成します。

コード例

<?php

-- 省略 --

if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ) {

	// 出力の設定
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=メッセージデータ.csv");
	header("Content-Transfer-Encoding: binary");

	// データベースに接続
	$mysqli = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME);

	// 接続エラーの確認
	if( !$mysqli->connect_errno ) {

		$sql = "SELECT * FROM message ORDER BY post_date ASC";
		$res = $mysqli->query($sql);

		if( $res ) {
			$message_array = $res->fetch_all(MYSQLI_ASSOC);
		}

		$mysqli->close();
	}

	// CSVデータを作成
	if( !empty($message_array) ) {

		// 1行目のラベル作成
		$csv_data .= '"ID","表示名","メッセージ","投稿日時"'."\n";

		foreach( $message_array as $value ) {

			// データを1行ずつCSVファイルに書き込む
			$csv_data .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n";
		}
	}

} else {

-- 省略 --

コードを順に解説します。

まず、外側にあるif文でファイルとして出力する投稿データがあるかを確認しています。
もし投稿データがあれば、CSVファイルの1行目を生成します。

// 1行目のラベル作成
$csv_data .= '"ID","表示名","メッセージ","投稿日時"'."\n";
作成している行のイメージ

CSVファイルの内容は$csv_dataに代入していきます。

CSV形式のデータは値を「 (ダブルクォーテーション)」で囲み、それぞれを「, (コンマ)」で区切ります。
そして、行末には改行コード「\n」を記述することで、行の終わりを指定します。
この処理を繰り返して、必要な数の行だけデータを並べてファイルを作成していきます。

(シングルクォーテーション)」で囲むと改行コードが通常のテキストとなってしまうため、行末の部分だけ「”」に切り替えている点に注意してください。

続いて、1行目と同じ形で投稿データの数だけループを繰り返して、ファイルの内容を$csv_dataに追記していきます。

foreach( $message_array as $value ) {

	// データを1行ずつCSVファイルに書き込む
	$csv_data .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n";
}

投稿データを1つずつ$valueに代入して、ファイルを作っていきます。
全ての投稿データをファイル内容として追記したらループが終了し、ファイルの作成も完了します。

ファイルを出力する

最後に、ファイルを出力してダウンロードするためのコードを追記します。

コード例

<?php

-- 省略 --

if( !empty($_SESSION['admin_login']) && $_SESSION['admin_login'] === true ) {

	// 出力の設定
	header("Content-Type: application/octet-stream");
	header("Content-Disposition: attachment; filename=メッセージデータ.csv");
	header("Content-Transfer-Encoding: binary");

	// データベースに接続
	$mysqli = new mysqli( DB_HOST, DB_USER, DB_PASS, DB_NAME);

	// 接続エラーの確認
	if( !$mysqli->connect_errno ) {

		$sql = "SELECT * FROM message ORDER BY post_date ASC";
		$res = $mysqli->query($sql);

		if( $res ) {
			$message_array = $res->fetch_all(MYSQLI_ASSOC);
		}

		$mysqli->close();
	}

	// CSVデータを作成
	if( !empty($message_array) ) {

	    // 1行目のラベル作成
		$csv_data .= '"ID","表示名","メッセージ","投稿日時"'."\n";

	    foreach( $message_array as $value ) {

	        // データを1行ずつCSVファイルに書き込む
            $csv_data .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n";
        }
	}

	// ファイルを出力	
	echo $csv_data;

} else {

-- 省略 --

ここまでファイル内容を書き込んできた$csv_dataecho関数で出力するだけで、ファイルとして出力することができます。
早速、「admin.php」からダウンロードボタンを押してみましょう。

ファイルのダウンロードが実行される

ファイルのダウンロードが実行されれば成功です。

ダウンロードされたファイルは、テキストエディタで開くと次のような内容が書き込まれています。

ファイルの内容例

"ID","表示名","メッセージ","投稿日時"
"1","涼子","データベースにデータを登録してみる","2019-03-28 16:38:28"
"2","テスト太郎","投稿のテストです","2019-03-28 20:02:58"
"3","康平","こんばんは!","2019-03-28 20:26:38"
"6","花子","セッションのテスト","2019-04-01 16:13:49"

ExcelやNumbersなど表計算ソフトで開くこともできます。

表計算ソフトでファイルを開いた例

投稿データのダウンロード機能を実装してきました。
次回は機能を拡張して、ダウンロードするデータの件数を選択できるようにしていきます。

今回作成したコード:Github

こちらの記事は役に立ちましたか?

ありがとうございます。
もしよろしければ、あわせてフィードバックや要望などをご入力ください。

ありがとうございます。
コメントを送信しました。