2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PHP CSVダウンロードの実装をしよう。 ※MySQLi、オブジェクト指向も学べます!

Last updated at Posted at 2021-06-14

はじめに

・PHPで、CSVでダウンロードを実装したい方
・MySQLiを使用して、DB操作を実装したい方。
・オブジェクト指向でコードを実装した方

CSVダウンロードの実装をしよう

CSVとは、**Comma Separated Valueの略称で、直訳するとカンマで区切った値という意味になります。なお、PHPでCSVを実装するには、header関数**を使用します。

######基本形(サンプルコード)

csv.php
<?php 

// 出力情報の設定
header("Content-Dispositionntent-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=GRAYCODE.csv");
header("Content-Transfer-Encoding: binary");

// 変数の初期化
$member = array();
$csv = null;

// 出力したいデータのサンプル
$member = array(
	array(
		'id' => 1,
		'name' => '山田太郎',
		'furigana' => 'やまだたろう',
		'email' => 'taroyamada@sample.com'
	),
	array(
		'id' => 3,
		'name' => '加藤明美',
		'furigana' => 'かとうあけみ',
		'email' => 'akemikato@sample.com'
	),
	array(
		'id' => 5,
		'name' => '佐藤健夫',
		'furigana' => 'さとうたけお',
		'email' => 'takeosato@sample.com'
	)
);

// 1行目のラベルを作成
$csv = '"ID","氏名","ふりがな","メールアドレス"' . "\n";


// 出力データを生成
foreach( $member as $value ) {
	$csv .= '"' . $value['id'] . '","' . $value['name'] . '", "' . $value['furigana'] . '","' . $value['email'] . '"' . "\n";
}

// CSVファイル出力
echo $csv;
return;
 ?>
csv_index.php
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title></title>
	<link rel="stylesheet" href="">
</head>
<body>
	<h1>CSV Download</h1>
	<form method="get" action="./csv.php">
    <input type="submit" name="btn_download" value="ダウンロード">
</form>
</body>
</html>

コード抜き出し解説①

コード抜き出し①
header("Content-Dispositionntent-Type: application/octet-stream");

**header関数で、HTTPヘッダの情報を送信します。ContentDispositionntentTypeでは、クライアントに返されたコンテンツがどのようなものかを伝え、application/octet-stream**はファイルの種類が分からないときなどに使用する、MIMEタイプを指定しています。

コード抜き出し解説②

コード抜き出②
header("Content-Disposition: attachment; filename=GRAYCODE.csv");

**Content-Disposition: attachmentで、ダウンロードファイルとして表示させ、filename=GRAYCODE.csvでファイル名を指定しています。
※今回のファイル名は、
GRAYCODE.csv**になります。

コード抜き出し解説③

コード抜き出③
header("Content-TransferEncoding:binary");

**Content-Transfer-Encoding:で、エンコーディング形式を伝え、binary**でバイナリーデータを指定します。

MySQLiを使ってDB操作を実装しよう

MySQLiとは、**MySQL improved extension**の略称です。MySQLと、MariaDBを操作するためのPHPの拡張機能で、オブジェクト指向で記述が可能です。

MySQLiのインスタンスを作成

MySQLiのインスタンスを作成
$mysqli = new mysqli('host_name', 'user_name', 'password','database_name'); 

インスタスの引数の説明

引数名 詳細
host_name ホスト名(localhost、127.0.0.1など)
user_name 使用するDBのユーザー名
password DBにログイン際のパスワード
database_name 使用するDBの名前
※引数は、各自の環境に合わして変更してください。

MySQLiでSQLクエリの実行

$mysqli->query(`SELECT * FROM test_table`);

今回の場合**SELECT * FROM test_tableで、test_table**のレコードを全て取得するSQL文を実行しています。
※他のSQL文でも可能。

DBに接続(オブジェクト指向での書き方)

// データベースへ接続
$mysqli = new mysqli('host_name', 'user_name', 'password', 'database_name');

// 接続エラーの確認
if ($mysqli->connect_errno) {
	echo $mysqli->connect_errno .':' .$mysqli->connect_error;
}

// 接続解除
$mysqli->close();

MySQLiのインスタンスを作成でDBに接続し、MySQLiプロパティを実装することでエラー処理などを記述。
empty関数を使用し、**if (!empty ($mysqli->connect_errno))**でも可能。

プロパティ 詳細
connect_errno 接続エラーの番号を返す
connect_error 接続エラーのメッセージを返す

オブジェクト指向で、実装しよう

全体のサンプルコード
db.php
<?php

// DB操作に必要な変数をゲッター、セッターで実装したクラス
class DbData {
	private static $sql_result = null;
	private static $message_array = array();

	public static function getSqlResult() {
		return self::$sql_result;
	}
	public static function getMessageArray() {
		return self::$message_array;
	}
	public static function setSqlResult($sql_result) {
		self::$sql_result = $sql_result;
	}
	public static function setMessageArray($message_array) {
		self::$message_array = $message_array;
	}
}

// 条件分岐で必要なSELECT文を実装するクラス
class DbSlect {
	private static $sql_select = null;
	private static $limt = "LIMIT";

	public static function getSqlSelect() {
		if (self::$sql_select == null) {
			self::$limt = null;
		}
		return "SELECT * FROM message ORDER BY post_date ASC"." ".self::$limt." ".self::$sql_select;
	}
	public static function setSqlSelect($sql_select) {
		if (!is_null($sql_select) && !is_numeric($sql_select)){
			throw new Exception('Error: Please enter a number or a string');
		}
		self::$sql_select = $sql_select;
	}
}
 ?>
csv.php
<?php 
// csvの操作を実装するクラス
class csvDownlod {
	private static $csv = null;

	public static function csvOpretion() {
		self::$csv = '"ID","表示名","メッセージ","投稿日時"'."\n";
		foreach (DbData::getMessageArray() as $value) {
			self::$csv .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n";
		}
		echo self::$csv;
	}
}return;
 ?>
dowonload.php
<?php 

// 外部ファイルの呼び出し
require_once('db.php');
require_once('csv.php');

// DB情報を定数で実装
define('DB_HOST', '127.0.0.1');
define('DB_USER', 'root');
define('DB_PASS', '各自のpass');
define('DB_NAME', 'board');


// mysqliクラスを使用し、GETパラメータの値で条件分岐
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

if (!empty ($mysqli->connect_errno)) {
	echo $mysqli->connect_errno .':' .$mysqli->connect_error;
}
$get_data = $_GET['download_number'];
if (!empty($get_data)) {
	if ($get_data === '10') {
		DbSlect::setSqlSelect(10);
	}elseif ($get_data === '30') {
		DbSlect::setSqlSelect(30);
	}else{
		DbSlect::setSqlSelect(null);
	}
}
DbData::setSqlResult($mysqli->query(DbSlect::getSqlSelect()));
DbData::setMessageArray(DbData::getSqlResult());
DbData::getMessageArray()->fetch_all(MYSQLI_ASSOC);
$mysqli->close();

// ヘッター関数を使用し、出力情報の設定
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=メッセージデータ.csv");
header("Content-Transfer-Encoding: binary");
csvDownlod::csvOpretion();
csv_index.php
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title></title>
	<link rel="stylesheet" href="">
</head>
<body>
	<form action="test_download.php" method="get">
	<select name="download_number">
		<option value="">全て</option>
		<option value="10">10</option>
		<option value="30">30</option>
	</select>
	<button type="submit" name="btn-submit" value="btn-submit">ダウンロード</button>
</form>
</body>
</html>

DB情報について

今回使用する、DB情報は以下になります↓

DB名 ユーザー名 テーブル名 カラム名① カラム名② カラム名③
message root id(int) view_name(varchar(100)) message(text) post_date(datetime)

コード抜き出し解説①

コード抜き出し解説①
class DbData {
	private static $sql_result = null;
	private static $message_array = array();

// 中略

ここでは、**DbDataクラスを定義しています。private static 〜 変数名とすることでクラスの外部からアクセス、変更不可の静的なプロパティ**を定義できます。

コード抜き出し②

コード抜き出し②
// 中略
public static function getSqlResult() {
        return self::$sql_result;
    }
    public static function getMessageArray() {
        return self::$message_array;
    }
// 中略

public static function get~() { ...とすることで、静的なメソッドを定義できまふす。このメソッドはGetterと呼ばれ、privateでクラス外部からからアクセス変更不可な、プロパティの値だけを返すメソッドの総称のことを指します。クラス内で静的なプロパティにアクセスする際には、self::$プロパティ名 になります。

動的なメソッドの場合はstaticをつけず、public function メソッド名() { ...
になり、動的なプロパティにアクセスする際には、**this->プロパティ名**となります。

コード抜き出し③

コード抜き出し③
// 中略
public static function setSqlResult($sql_result) {
		self::$sql_result = $sql_result;
	}
	public static function setMessageArray($message_array) {
		self::$message_array = $message_array;
	}
// 中略

**public static function set~() { ...とすることで、コード抜き出し②と同様に、静的なメソッドを定義することができる。このメソッドはSetterと呼ばれ、privateでクラス外部からからアクセス変更不可な、プロパティの値を変更するメソッドの総称のことを指します。
Setterを使用しないと、privateのプロパティ**を変更できない仕組みになっています。

コード抜き出し④

コード抜き出し④
class DbSlect {
	// 中略
	public static function getSqlSelect() {
		if (self::$sql_select == null) {
			self::$limt = null;
		}
		return "SELECT * FROM message ORDER BY post_date ASC"." ".self::$limt." ".self::$sql_select;
	}
// 中略

ここでは、**DbSlectクラス**を定義しています。

if (self::$sql_select == null) { self::$limt = null; }
のコードで、ダウンロード件数を指定しない場合はプロパティの**$limtの値をnull**にしている。これにより、ダウンロード件数を指定しない場合は、DBから全てのデータを取得する条件分分岐が可能になる。

また、**return "SELECT * FROM message ORDER BY post_date ASC"." ".self::$limt." ".self::$sql_select;で、SELECT文**に当たる文字列を実装しています。

コード抜き出し⑤

コード抜き出し⑤
class csvDownlod {
	private static $csv = null;

	public static function csvOpretion() {
		self::$csv = '"ID","表示名","メッセージ","投稿日時"'."\n";
		foreach (DbData::getMessageArray() as $value) {
			self::$csv .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n";
		}
		echo self::$csv;
	}
}return

ここでは、**csvDownlodクラス**を定義しています。

self::$csv = '"ID","表示名","メッセージ","投稿日時"'."\n"; foreach (DbData::getMessageArray() as $value) { self::$csv .= '"' . $value['id'] . '","' . $value['view_name'] . '","' . $value['message'] . '","' . $value['post_date'] . "\"\n"; } echo self::$csv; } }return
で、DBから取得したデータをcsvに実装するために、**カンマ区切りで、$value**に値を格納し、DBのデータも同様に配列として格納することで、カンマ区切りになっています。

コード抜き出し⑥

コード抜き出し⑥
// 中略
public static function setSqlSelect($sql_select) {
		if (!is_null($sql_select) && !is_numeric($sql_select)){
			throw new Exception('Error: Please enter a number or a string');
		}
		self::$sql_select = $sql_select;
	}
}return
 ?>

**if (!is_null($sql_select) && !is_numeric($sql_select)){ throw new Exception('Error: Please enter a number or a string'); }では、Setter**でプロパティの値をセットしたり変更する際に、値の検査を行なっている。

コード抜き出し⑦

コード抜き出し⑦
// 中略
DbData::setSqlResult($mysqli->query(DbSlect::getSqlSelect()));
DbData::setMessageArray(DbData::getSqlResult());
DbData::getMessageArray()->fetch_all(MYSQLI_ASSOC);

// 中略
csvDownlod::csvOpretion();

ここでは、DbDataクラスとDbSlectクラスの静的メソッドを呼び出しています。静的メソッドは、インスタンスを作成せずに呼び出すことが可能で、**クラス名::静的メソッド名**と記述します。

まとめ

・ヘッター関数を使用して、CSVの出力の設定をする。

・MySQLiクラスのインスタスを作成し、引数にDB情報を設定する。

・**private static プロパティ名;**で、クラスの外部からアクセスや変更できない、静的なプロパティを定義。

・**private プロパティ名;**で、クラスの外部からアクセスや変更できない、動的なプロパティを定義。

・**public static function メソッド名(){ ...**で、クラス外部からアクセス可能な静的なメソッドを定義。

・**public function メソッド名(){ ...**で、クラス外部からアクセス可能な動的なメソッドを定義。

・静的なプロパティにアクセスするには、**self:: $プロパティ名**で、アクセス可能。

・動的なプロパティにアクセスするには、**this->プロパティ名**で、アクセス可能。

参考サイト

mysqliを使ってMySQL/MariaDBのデータベースへ接続

データをCSVファイルとしてダウンロードする

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?