PHP開発日記:GETで検索(1ページにつきn件表示)
昨日からの課題だった、「1ページにつきn件の検索結果を表示、画面下部のリンクで切り替え」という機能について研究。
今日変更したphpファイルの変更箇所は以下の通り。
config.php
//検索設定
define('SEARCH_DISP_LIMIT',100);
1ページあたりの表示件数を定数として設定。上記の設定では1ページあたり100件の検索結果が表示される。
db_helper.php
function search_address($dbh,$addno,$add1,$add2,$add3,$pagecount){
$result=;
$sql="select addno,add1,add2,add3 from address where 1=1";
if ($addno!=='') {
$sql=$sql." and addno like :addno";
}
if ($add1!=='指定しない') {
$sql=$sql." and add1 like :add1";
}
if ($add2!=='') {
$sql=$sql." and add2 like :add2";
}
if ($add3!=='') {
$sql=$sql.=" and add3 like :add3";
}
$sql=$sql." order by addno limit :pagecount , :pagelimit";
$stmt=$dbh->prepare($sql);
if ($addno!=='') {
$stmt->bindvalue(':addno','%'.$addno.'%',PDO::PARAM_STR);
}
if ($add1!=='指定しない') {
$stmt->bindvalue(':add1','%'.$add1.'%',PDO::PARAM_STR);
}
if ($add2!=='') {
$stmt->bindvalue(':add2','%'.$add2.'%',PDO::PARAM_STR);
}
if ($add3!=='') {
$stmt->bindvalue(':add3','%'.$add3.'%',PDO::PARAM_STR);
}
$stmt->bindvalue(':pagecount',$pagecount,PDO::PARAM_INT);
$stmt->bindvalue(':pagelimit',SEARCH_DISP_LIMIT,PDO::PARAM_INT);
$stmt->execute();
while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
$result=$row;
}
return $result;
}function count_address($dbh,$addno,$add1,$add2,$add3,$pagecount){
$count=0;
$sql="select count(addno) as count from address where 1=1";
if ($addno!=='') {
$sql=$sql." and addno like :addno";
}
if ($add1!=='指定しない') {
$sql=$sql." and add1 like :add1";
}
if ($add2!=='') {
$sql=$sql." and add2 like :add2";
}
if ($add3!=='') {
$sql=$sql.=" and add3 like :add3";
}
$stmt=$dbh->prepare($sql);
if ($addno!=='') {
$stmt->bindvalue(':addno','%'.$addno.'%',PDO::PARAM_STR);
}
if ($add1!=='指定しない') {
$stmt->bindvalue(':add1','%'.$add1.'%',PDO::PARAM_STR);
}
if ($add2!=='') {
$stmt->bindvalue(':add2','%'.$add2.'%',PDO::PARAM_STR);
}
if ($add3!=='') {
$stmt->bindvalue(':add3','%'.$add3.'%',PDO::PARAM_STR);
}
$stmt->execute();
while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
$count=$row;
}
return $count;
}
search_address関数で検索結果を、count_address関数で全体の件数を取得。search_addressについて、SQLの最後にlimit x , yを使っているのがポイント(検索結果のx件目からy件表示する)。count_addressでは全体のレコード数をcountを使って取得している。
search.php
if (isset($_GET['addno']) or isset($_GET['add1']) or isset($_GET['add2']) or isset($_GET['add3'])) {
$addno=$_GET['addno'];
$addno=html_escape($addno);
$add1=$_GET['add1'];
$add1=html_escape($add1);
$add2=$_GET['add2'];
$add2=html_escape($add2);
$add3=$_GET['add3'];
$add3=html_escape($add3);
$page=$_GET['page'];
$page=(int)html_escape($page);
$result=[];
$tmpcount=0;
$count=0;
$dbh=get_db_connect();
// 検索、レコード取得
$result=search_address($dbh,$addno,$add1,$add2,$add3,$page);
$tmpcount=count_address($dbh,$addno,$add1,$add2,$add3);
$count=intval($tmpcount['count']);
}
$_GET['page']を新しく設定。これで何ページ目にあたるデータを表示するのかを指定する。数値型に変換して$pageに格納する。
serach_view.php
<!-- 表示 -->
<?php if(isset($addno) or isset($add1) or isset($add2) or isset($add3)): ?>
<?php if ($count>0): ?>
<?php if($count>$page+SEARCH_DISP_LIMIT): ?>
<p><?php echo $count; ?>件ヒット!(<?php echo $page+1;?>~<?php echo $page+SEARCH_DISP_LIMIT;?>件目)</p>
<?php else: ?>
<p><?php echo $count; ?>件ヒット!(<?php echo $page+1;?>~<?php echo $count;?>件目)</p>
<?php endif; ?>
<table border="1">
<tr>
<th>郵便番号</th>
<th>都道府県</th>
<th>市区町村</th>
<th>町域</th>
</tr>
<?php foreach ($result as $row): ?>
<tr>
<td><?php echo $row['addno']; ?></td>
<td><?php echo $row['add1']; ?></td>
<td><?php echo $row['add2']; ?></td>
<td><?php echo $row['add3']; ?></td>
</tr>
<?php endforeach; ?>
</table>
<!-- n件ごとに1ページ表示 -->
<?php for($i=0;$i<=$count;$i+=SEARCH_DISP_LIMIT) {?>
<?php $pagecount+=1 ?>
<a href="search.php?addno=<?php echo $addno; ?>&add1=<?php echo $add1; ?>&add2=<?php echo $add2; ?>&add3=<?php echo $add3; ?>&page=<?php echo $i;?>"><?php echo $pagecount; ?></a>
<?php } ?>
<?php else: ?>
<p>該当するデータはありません。</p>
<?php endif; ?>
<?php endif; ?>
検索結果を表示する表を作った後、forループでaタグを量産していく。aタグのリンク先として現在のsearch.phpを指定するが、このときにGETで渡す値もタグにべた書きする。こうすることでリンクが改行されることなく並ぶ。
これらの変更を行い、検索画面は以下のようになった。
検索条件を指定せずに検索。本来ならば12万件以上のデータを表示しようとするが、今回の変更によって「12万行のうちの1~100件目」のみを表示するようになったのでとても処理が軽い。
ページ下部は以下のようになっている。
検索結果が多すぎるのでリンクが無数に並んでいるが、やりたかったことは達成した。このうち「2」のリンクをクリックする。
「2」のリンクをクリックすると画面が切り替わり、101件目~200件目を表示するようになった。
今回の住所録機能についてはこれで完成とする。
意外とサクサク進んでいる。明日からはTwitterのAPIを使うための勉強を行う予定。というかJSON?が必要らしいんだけど何それレベルなのでまずはそこから。Javascriptがこの環境で使えるのかどうか…。