データベース入門(ツール作成)

1つ前の記事でSQL文の紹介をしました。

データベース入門(SQL文)
以前の記事ではMySQLをphpMyAdminで操作する基本を解説しました。 しかし、実際これだけでは困ったことも多いです。例えば1つ前の血圧管理すると言っても、他の人のも管理するようになると都度その人にphpMyAdminを開いても...

 

この記事ではツールからSQL文を利用してデータベースを操作していきます。

xamppで一緒にインストールされているphpで簡単なブラウザで動くツールを作ります。

とりあえず仕様を決める

  • フォームに日付と血圧上下と脈拍を入力できる。
  • 別のページでは入力されたデータがすべて見れる
  • データ閲覧ページでは日付で検索できる

この内容で行きます。

とりあえず先にページ作る

ここは本題ではないのでサクッと作ってしまいます。

入力フォーム

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>入力フォーム</title>
	</head>
	<body>
		<div>
			<form action="add.php" method="POST" accept-charset="utf-8">
				<p>最高血圧: <input type="text" name="high" />
				<p>最低血圧: <input type="text" name="low" />
				<p>脈拍: <input type="text" name="pulse" />
				<p><input type="submit" value="送信" />
			</form>
		</div>
	</body>
</html>

addform.htmlという名前で、xampp\htdocs\healthフォルダーの中に保存します。

文字コードはutf-8を設定してください。(メモ帳だとうまく設定できないのでsakuraエディターとかemEditorとかの高機能テキストエディターを利用してください。)

これで入力フォーム出来ました。確認する際は「http://localhost/health/addform.html」です。

閲覧ページ

登録されたデータを閲覧するページを作ります。これはDBにアクセスする必要があるのでhtmlではなくphpですが、まずは見た目だけ作りましょう。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>閲覧ページ</title>
		<style>
			table {
				border-collapse: collapse;
			}
			
			th, td {
				border: solid 1px #000;
			}
		</style>
	</head>
	<body>
		<div>
			<table>
				<thead>
					<tr>
						<th>日付</th>
						<th>最高</th>
						<th>最低</th>
						<th>脈拍</th>
					</tr>
				</thead>
				<tbody>
					<!-- ここをphpで出力する -->
					<tr>
						<td>xxxx-xx-xx xx:xx:xx</td>
						<td>xxx</td>
						<td>xxx</td>
						<td>xxx</td>
					</tr>
				</tbody>
			</table>
		</div>
		<div>
			<a href="addform.html">追加フォーム</a>
		</div>
	</body>
</html>

これはindex.phpという名前で保存しましょう。

確認する際は「http://localhost/health/」です。(index.phpというファイル名は省略できます)

今xxxとなっている部分をDBからデータを取得して表示するようにします。

DB連携

phpではmysqliというものを使ってデータベースと連携します。

index.phpを弄ります。

<?php
	// データーベースへ接続
	$db = new mysqli('localhost', 'root', '', 'health');
	// SQL文を登録
	$state = $db->prepare('SELECT timing, high, low, pulse FROM blood_pressures;');
	// 以下の変数にDBの値を取得する
	$timing = '';
	$high = 0;
	$low = 0;
	$pulse = 0;
	
	// 引数で指定した変数に値が設定されるように登録する
	$state->bind_result($timing, $high, $low, $pulse);
	// 登録したSQL文を実行
	$state->execute();
?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>閲覧ページ</title>
		<style>
			table {
				border-collapse: collapse;
			}
			
			th, td {
				border: solid 1px #000;
			}
		</style>
	</head>
	<body>
		<div>
			<table>
				<thead>
					<tr>
						<th>日付</th>
						<th>最高</th>
						<th>最低</th>
						<th>脈拍</th>
					</tr>
				</thead>
				<tbody>
	<!-- 行を順番に取得する -->
<?php while ($state->fetch()) : ?>
					<tr>
						<td><?= $timing ?></td>
						<td><?= $high ?></td>
						<td><?= $low ?></td>
						<td><?= $pulse ?></td>
					</tr>

<?php endwhile; ?>
				</tbody>
			</table>
		</div>
		<div>
			<a href="addform.html">追加フォーム</a>
		</div>
	</body>
</html>
<?php
	// DBへの接続を切断
	$state->close();
	$db->close();
?>

弄りました。概ね先ほどのHTML文と同じですが、先頭にDBへのアクセスと、SQL文が記述されています。

また、<table>の中ではSQL文の結果をwhileで行がなくなるまで繰り返しています。

順番に見ていきます。

$db = new mysqli(‘localhost’, ‘root’, ”, ‘health’);

データベースへ接続します。

  • ‘localhost’
    • 接続するデータベースのURLです。localhostはphpが動いているPCと同じPCを指します。
  • ‘root’
    • データベースに接続する際のユーザー名(ログオン名)です。
    • 接続する際のパスワードです。ユーザー毎に設定されていますが、rootの初期は空っぽです。
  • ‘health’
    • 操作するデーターベース名の指定です。

mysqliでのデータベース接続ではこの順番のとおりに値を設定すると接続できます。

他の環境では使うものや、指定の順番等違うかもしれませんが、設定する物は変わらないと思います。

$state = $db->prepare(‘SELECT timing, high, low, pulse FROM blood_pressures;’);

SQL文が出てきました。blood_pressuresテーブルから全件取得します。

mysqliではprepareを利用してSQL文を登録します。その後いくらか設定したらexecuteで実際に処理が実行されます。

$state->bind_result($timing, $high, $low, $pulse);

bind_resultでは指定した変数にDBでSELECTした結果が自動で設定されるようになります。

これはSELECT文のカラムのところと数と順番を合わせる必要があります。

$state->execute();

前述のとおり、事前に設定したSQL文を実行します。

while ($state->fetch()) :

fetchで実行した結果を1行ずつbind_resultで指定した変数に設定していきます。

while () : endwhile;で行が全て処理し終わるまでwhile~endwhileの間のものを繰り返し処理します。

whileの中は<?= 変数 ?>の形で、指定の変数をそこに置き換えます。

phpdbtool-select

このようになりました。

右クリックでソースを確認すると、実際にwhileでどのようなhtmlが出力されているか見ることが出来ます。

追加フォーム

では追加フォームを作ります。名前はadd.phpにしておきます。

ここでは追加処理だけでHTMLは無しで、完了したらindex.phpに自動で遷移するようにします。

<?php
	// データーベースへ接続
	$db = new mysqli('localhost', 'root', '', 'health');
	// SQL文を登録
	$state = $db->prepare('INSERT INTO blood_pressures (timing, high, low, pulse) VALUES (NOW(), ?, ?, ?);');

	// フォームで設定されたデータを変数に一度保存
	$high = $_POST['high'];
	$low = $_POST['low'];
	$pulse = $_POST['pulse'];

	// ?の部分を置き換える値を指定する
	$state->bind_param('iii', $high, $low, $pulse);
	
	// SQL文実行
	$state->execute();
	
	// データベースとの接続を切断
	$state->close();
	$db->close();
	
	// index.phpへ遷移
	header('Location: index.php');
?>

これも順番に解説します。

$db = new mysqli(‘localhost’, ‘root’, ”, ‘health’);

先ほどと一緒でデータベースへ接続しています。

$state = $db->prepare(‘INSERT INTO blood_pressures (timing, high, low, pulse) VALUES (NOW(), ?, ?, ?);’);

INSERT文を登録しています。

?というのが出ていますが、これは後で?の部分をちゃんとして値に置き換えますよ、という指定です。

これによって、一度に何個もINSERTする際にSQL文を動的に作る必要が無かったり、SQLインジェクションと言う攻撃に対応する事が出来たりとメリットが多いです。

$high = $_POST[‘high’]; $low = $_POST[‘low’]; $pulse = $_POST[‘pulse’];

フォームに設定された値を変数に代入しています。

(ほんとはfilter_input使った方がいいけど…)

$state->bind_param(‘iii’, $high, $low, $pulse);

先ほどのprepareで書いた?を置き換えるのがココです。

?の部分が前から順番に$high、$low、$pulse変数の中身に置き換わります。

‘iii’はbind_paramに渡す変数が数値3つと言う意味です。

$state->execute();

実際にSQL文が実行されます。?の中身は最後にbind_paramされた内容に置き換わっています。

なので、bind_param → execute → bind_param → executeと実行していくことで複数の行をお手軽に追加する事が出来ます。

header(‘Location: index.php’);

これはデータベースとは関係ありません。index.phpへページ移動してくださいという命令です。

日付指定できるようにする

index.phpに日付指定できるように機能追加します。

GET(URLの後ろに?をつけるやつ)で日付を指定して、それでSELECT文にWHEREを指定するようにします。

<?php
	$begin = null;
	$end = null;

	// GETで指定された値を取得
	if (isset($_GET['begin'])) {
		$begin = $_GET['begin'];
	} else {
		// 指定が無ければ全件取得できる昔の日にちに
		$begin = '1970-01-01';
	}
	if (isset($_GET['end'])) {
		$end = $_GET['end'];
	} else {
		// 指定が無ければ全件取得できる未来の日にちに
		$end = '3000-01-01';
	}

	// データーベースへ接続
	$db = new mysqli('localhost', 'root', '', 'health');
	// SQL文を登録
	$state = $db->prepare('SELECT timing, high, low, pulse FROM blood_pressures WHERE timing BETWEEN ? AND ?;');
	
	// WHEREの条件に使うbeginとendを登録
	$state->bind_param('ss', $begin, $end);
	
	$timing = '';
	$high = 0;
	$low = 0;
	$pulse = 0;
	
	// 引数で指定した変数に値が設定されるように登録する
	$state->bind_result($timing, $high, $low, $pulse);
	// 登録したSQL文を実行
	$state->execute();
?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>閲覧ページ</title>
		<style>
			table {
				border-collapse: collapse;
			}
			
			th, td {
				border: solid 1px #000;
			}
		</style>
	</head>
	<body>
		<div>
			<table>
				<thead>
					<tr>
						<th>日付</th>
						<th>最高</th>
						<th>最低</th>
						<th>脈拍</th>
					</tr>
				</thead>
				<tbody>
	<!-- 行を順番に取得する -->
<?php while ($state->fetch()) : ?>
					<tr>
						<td><?= $timing ?></td>
						<td><?= $high ?></td>
						<td><?= $low ?></td>
						<td><?= $pulse ?></td>
					</tr>

<?php endwhile; ?>
				</tbody>
			</table>
		</div>
		<div>
			<a href="addform.html">追加フォーム</a>
		</div>
	</body>
</html>
<?php
	// DBへの接続を切断
	$state->close();
	$db->close();
?>
GETを取得するように変更
	// GETで指定された値を取得
	if (isset($_GET['begin'])) {
		$begin = $_GET['begin'];
	} else {
		// 指定が無ければ全件取得できる昔の日にちに
		$begin = '1970-01-01';
	}
	if (isset($_GET['end'])) {
		$end = $_GET['end'];
	} else {
		// 指定が無ければ全件取得できる未来の日にちに
		$end = '3000-01-01';
	}

GETで指定された値を取得できるようにしました。

GETで指定されていない場合は遥か昔と遥か未来の値を勝手に設定するようにしています。

SQL文を少し変更
$state = $db->prepare('SELECT timing, high, low, pulse FROM blood_pressures WHERE timing BETWEEN ? AND ?;');

WHEREを増やしました。

条件は「timing BETWEEN ? AND ?;」でtimingがbeginとendの間の場合はと言う指定です。

(「timing >= ? AND timing <= ?」と同等です。)

$state->bind_param(‘ss’, $begin, $end);

INSERTの時と一緒です。?の部分を置き換えるように指定しています。

‘ss’はbind_paramに文字列を2つ設定していますという指定です。

これで日付指定もできました。

試す際は「http://localhost/health/index.php?begin=2016-05-30&end=2016-05-31」こんな感じです。これで5-30~5-31の間の行が取得出来ています。

phpdbtool-select2

まとめ

これでDBの内容の確認と追加が出来ました。

DBと連携したツールは基本的にこの延長です。大規模な奴でもそう大きくは変わらないでしょう。

DBの中身を条件に従って抽出したり、ユーザーからの入力をルールに従ってDBに保存する、もしくは既存データを変更する。

これぐらいでしょう。テーブルの数の多寡や、条件の複雑さ等は規模で大分変わってくるとは思いますが・・・

多少どうこしても、パソコンが壊れることはまずまずないでしょうし、いろいろ弄ってみて動きを確認して覚えていくのが良いと思います。

タイトルとURLをコピーしました