PHP実習:MySQLのデータを検索&取得
昨日の続きをやっていきます。
第7章-05
昨日の最後のPHPについて、書き換えてデータ取得用のコードを作成する。
<?php
$dsn='mysql:dbname=user;host=localhost;charset=utf8';
$user='root';
$password='';try {
$dbh=new PDO($dsn,$user,$password);
$dbh -> setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);// 01.SQL作成
$sql="select * from user";
$stmt=$dbh->prepare($sql);
$stmt->execute();
$data=array();// 02.行数取得
$count=$stmt->rowCount();// 03.1件ずつデータ取得
while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
// 04.配列$dataに行を格納していく$data=$row;
}
echo "処理が終了しました";
} catch (PDOException $e) {
print($e->getMessage());
die();
}// 05.$dataの中身を確認
var_dump($count);
var_dump($data);
01.SQL作成
02.行数取得
$stmt->execute()を実行したあとは様々なデータが$stmtの中に入っている。
$stmt->rowCount()では行数を取得することができる。
03.1行ずつデータ取得
$stmt->fetch(PDO::FETCH_ASSOC)では1行のデータを連想配列で取得する。fetchというのは1行を取り出すということで、これをwhileの条件式とすることで該当の行があるだけ繰り返し取得してくれる。
04.配列$dataにデータを格納していく
これを$dataに格納することで、$dataは二次元配列になる。$dataの後ろに配列の合図であるをつけるのを忘れないこと。
05.$dataの中身を確認
デベロッパーツールで確認するとこのようになる。
次に、先ほどのphpファイルにコードを追加してブラウザで表として画面に表示していく。
<?php
$dsn='mysql:dbname=user;host=localhost;charset=utf8';
$user='root';
$password='';try {
// 省略
} catch (PDOException $e) {
print($e->getMessage());
die();
}?>
<html>
<body>
<h1>会員データ一覧表</h1>
<table border=1>
<tr><th>id</th><th>名前</th><th>年齢</th><th>メールアドレス</th></tr>
<?php foreach ($data as $row): ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
<td><?php echo $row['age']; ?></td>
<td><?php echo $row['email']; ?></td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
これで表示ができた。
第6章-06 実習
これまでPOST、変数、MySQL、foreachを学んだ。ここまでの集大成として、データベースの中を検索してブラウザに表示するシステムを作る。
今回は名前から会員が検索できるようにする。ある文字を含む名前の一覧を表示できるように作る。制作の流れは、
- 送信ページを作る
- 送信データの取得とデータベース捜査
- foreachを使って表示
となる。要件定義として、
- フォームからの値にはbindValue()を使う
- nameのカラムをLikeを使ってあいまい検索
- 一覧はforeachを使ってHTML内に出力
この3点がある。また、自分が開発する際には各章の実習とそれ以外で環境を分けているので実習用の環境にMySQLでデータベースを作るところから行う。
…と思って実習用のフォルダでuserデータベースを作ろうとしたら、既に存在するとのメッセージが出た。同じ仮想マシンで1つのデータベースを共有しているのだろうか…。とりあえずテーブルの存在確認もとれたので、このまま開発していく。
まずは送信ページのHTML部分を作成。
<html>
<head>
<meta charset="utf-8">
<title="検索アプリ">
</head>
<body>
<h1>検索アプリ</h1>
<p>名前の一致する会員を一覧にしよう</p>
<form action="search_receive.php" method="POST">
<label>お名前</label>
<input type="text" name="name">
<input type="submit" value="検索する">
</form>
</body>
</html>
次に、データの受信側となるsearch_receive.phpを作成する。
<?php
$dsn='mysql:dbname=user;host=localhost;charset=utf8';
$user='root';
$password='';try {
$dbh=new PDO($dsn,$user,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$sql="select * from user";
$stmt=dbh->prepare($sql);
$stmt->execute();$count=$stmt->rowCount();
while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
$data=$row;
}
echo "処理が終了しました";
} catch (PDOException $e) {
echo ($e->getMessage());
die();
}
?><html>
<body>
<h1>会員データ一覧</h1>
<p><?php echo $count.'件見つかりました。'; ?></p>
<table border=1>
<tr><th>id</th><h>名前</th></tr>
<?php foreach ($data as $row) : ?>
<tr>
<td><?php echo $row['id']; ?><td>
<td><?php echo $row['name']; ?><td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
今回はidとnameのみ出力する。
受信ページの最初でPOSTされてきたデータを受信する。
<?php
if ($_SERVER['REQUEST_METHOD']==='POST') {
$name=$_POST['name'];
}
$dsn='mysql:dbname=user;host=localhost;charset=utf8';
$user='root';
$password='';// 省略
これで$nameにPOSTされた内容が入る。
次は受信ページのSQLなどを書き換える。
$data=; // 配列初期化
try {
$dbh=new PDO($dsn,$user,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$sql="select id,name from user where name like :user";
$stmt=dbh->prepare($sql);
$stmt->bindValue(':name','%'.$name.'%',PDO::PARAM_STR);
$stmt->execute();
最初に$dataを配列として初期化しておく。array()以外に、PHP5.4以降は短縮構文で[]も使えるようになっている。この初期化はデータが1件もなかった場合に「Undefined」が出ることを防ぐ役割がある。
これでシステムが完成したので、実行してみると…
これにて完成。
しかし、この状態で検索をかけて該当がなかった場合は次のようになる。
検索でヒットしなかった場合、表を出さないように試してみる。
<html>
<body>
<h1>会員データ一覧</h1>
<?php if ($count==0) { ?>
<p><?php echo '該当はありません。'; ?></p>
<?php } else{ ?>
<p><?php echo $count.'件見つかりました。'; ?></p>
<table border=1>
<tr><th>id</th><th>名前</th></tr>
<?php foreach ($data as $row) : ?>
<tr>
<td><?php echo $row['id']; ?></td>
<td><?php echo $row['name']; ?></td>
</tr>
<?php endforeach; ?>
</table><?php } ?>
</body>
</html>
うまくいった!!しかし、最初はifの条件式をこのように書いていた。
if($count=0){
これではうまくいくわけがない。比較演算子は==もしくは===で書き、===の方がデータ型までチェックするので厳密な判定ができる。仕事の癖でつい…。
正しくは以下の通り。
if($count===0){
もしくは
if($count==0){
言語ごとにこのような違いがあるので、何を書いているのかで使い分けができるようになりたい。