あーる学習帳

自分が勉強したことや気になることなど、99%自分用です。コードを書いてるのでPCから閲覧を推奨。

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で渡す値もタグにべた書きする。こうすることでリンクが改行されることなく並ぶ。

 

これらの変更を行い、検索画面は以下のようになった。

f:id:R_de_aru:20180713235106p:plain

検索条件を指定せずに検索。本来ならば12万件以上のデータを表示しようとするが、今回の変更によって「12万行のうちの1~100件目」のみを表示するようになったのでとても処理が軽い。

ページ下部は以下のようになっている。

f:id:R_de_aru:20180713235231p:plain

検索結果が多すぎるのでリンクが無数に並んでいるが、やりたかったことは達成した。このうち「2」のリンクをクリックする。

f:id:R_de_aru:20180713235315p:plain

「2」のリンクをクリックすると画面が切り替わり、101件目~200件目を表示するようになった。

 

今回の住所録機能についてはこれで完成とする。

意外とサクサク進んでいる。明日からはTwitterのAPIを使うための勉強を行う予定。というかJSON?が必要らしいんだけど何それレベルなのでまずはそこから。Javascriptがこの環境で使えるのかどうか…。