4.2.8.検索結果の表示
最後に検索結果を出力する画面です。ある条件によりDB検索を行った結果は、一般に
その件数を予測できません。クライアント側に対して大量のデータを一度に返してしま
うのは、ネットワーク負荷や画面の応答速度の面からも避けるべきです。出力データ件
数が多い可能性がある場合、ページ制御を行うことを考慮する必要があります。
zip_display()に渡す引数は、検索結果全体を一定の行数で区切り、その中の何ペー
ジ目を表示するのか指示する数値です。先頭のページなら0になります。
[zip_display.inc]
1 <?php
2 //
3 // 検索結果の表示
4 // 引数:ページ番号
5 //
6 function zip_display($page)
7 {
8 if (DEBUG) {
9 print "zip_display($page)<br>\n";
10 }
11 $type = $_POST['type'];
12 $zip7 = $_POST['zip7'];
13 $pref_j = $_POST['pref_j'];
14 $city_j = $_POST['city_j'];
15 $count = $_POST['count'];
16 $db = sqlite_open(DB) or die(DB . " がオープンできません。\n");
17 $select_phrase = "SELECT zip7,pref_j,city_j,town_j FROM zip ";
18 if ($type == 1) { // 郵便番号で検索
19 $where_clause = "WHERE zip7 LIKE '$zip7%'";
20 } else { // 住所で検索
21 $where_clause = "WHERE 0=0";
22 if (strlen($pref_j) > 0) {
23 $where_clause .= " AND pref_j = '$pref_j'";
24 }
25 if (strlen($city_j) > 0) {
26 $where_clause .= " AND city_j = '$city_j'";
27 }
28 }
29 //
30 // 新規条件指定時(セッションデータとして保存)
31 //
32 if ($page == 0) {
33 $sql = "SELECT COUNT(*) FROM zip " . $where_clause;
34 $ar = sqlite_array_query($db, $sql, SQLITE_NUM);
35 $count = $ar[0][0]; // 新しい条件に該当する件数
36 $_SESSION['type'] = $type;
37 $_SESSION['zip7'] = $zip7;
38 $_SESSION['pref_j'] = $pref_j;
39 $_SESSION['city_j'] = $city_j;
40 $_SESSION['count'] = $count;
41 if (DEBUG) {
42 print "\$_SESSION[] = "; print_r($_SESSION); print "<br>\n";
43 }
44 }
45 $sql = $select_phrase . $where_clause
46 . " LIMIT " . RECORD_PER_PAGE
47 . " OFFSET " . $page * RECORD_PER_PAGE;
48 //
49 // ページ制御部分の表示
50 //
51 $pages = $count / RECORD_PER_PAGE; // ページ数
52 if ($pages > 1) {
53 print "検索結果ページ:";
54 for ($i=0; $i<$pages; $i++) {
55 if ($i == $page) {
56 printf(" %d\n", $i+1);
57 } else {
58 printf(" <a href=\"{$_SERVER['PHP_SELF']}?page=%d\">%d</a>\n",
59 $i, $i+1);
60 }
61 }
62 if ($page+1 < $pages) {
63 printf(
64 " <a href=\"{$_SERVER['PHP_SELF']}?page=%d\">次ページ</a><br>\n",
65 $page+1);
66 }
67 }
68
69 if (DEBUG) { print "$sql<br>\n"; }
70
71 $res = sqlite_query($db, $sql); // SQL の発行
72 $rows = sqlite_num_rows($res); // 結果の行数
73 if ($rows > 0) {
74 print "<table border>\n"
75 . "<tr><th>郵便番号<th>都道府県<th>市区町村<th>町域</tr>\n";
76 for ($i=0; $i<$rows; $i++) {
77 $row = sqlite_fetch_array($res, SQLITE_ASSOC);
78 printf("<tr><td>%s<td>%s<td>%s<td>%s</tr>\n",
79 $row['zip7'], $row['pref_j'], $row['city_j'], $row['town_j']);
80 }
81 print("</table>\n");
82 } else {
83 print "該当するデータはありません。\n";
84 }
85 sqlite_close($db);
86 print "</body></html>";
87 } // zip_display();
88 ?>
16行目でデータベースを開き、17行目ではレコードを抽出するためのSQL文の先頭部
分を作って$select_phraseにセットしておきます。18〜28行目では、SELECTで指定する
WHERE句だけを、別途$where_clauseにセットします。
32〜44行目では、$where_clauseで抽出されるレコード全体の件数を求めて、現在の
抽出条件とともにセッション変数に保存します。この処理は当該スクリプトが呼び出さ
れるたびに行っても正しく動作しますが、速度的に不利なので、先頭ページ表示時のみ
で行われるように条件を限定しています。
45〜47行目で実際に抽出をかけるためのSQL文を生成します。この関数の引数である
$pageが絞り込み条件として使われています。WHRE句による抽出されたレコードの集合
(レコードセット)の中からOFFSETで指定したレコード番号(先頭は0)から数えて、
LIMITで指定したレコード数分だけのレコードを取り出しています。
次に、51行目では検索結果が全部で何ページあるのかを算出しています。これが1ペ
ージに収まるのであれば問題ありませんが、2ページ以上にまたがる場合、図4-7のよう
に、検索結果が全部で何ページあるのか、また現在何ページ目を表示中なのかという、
ページ制御用のナビゲータを表示します(52〜67行目)。
やっと準備完了です。71行目でSQLを発行し、次の行で取り出した行数を取得します。
73〜84行で、行数分だけループしながらHTMLの表を構成しています。