検索結果の表示
検索フォームから送信された検索条件をFileMakerに送り、検索結果を受け取ります。検索結果が多数の場合は、ページ分割して表示し、次のページなどのリンクをたどりながら表示するレコードの範囲を切り替えていけるようにします。
考慮しなければならないのは、
- 1ページに表示する件数
- 取得するレコードの開始位置
- 表示するレコードの内容を切り替える「前/次ページへのリンク」の作成
となります。
この点を踏まえて、検索条件を処理して検索結果を表示するページを作ります。
<?php //文字コードの指定 header("Content-Type: text/html;charset=utf-8"); //APIのインクルード include_once('FileMaker.php'); //レコード取得開始位置の指定 ※1 if(isset($_GET['skip'])){ $skip = $_GET['skip']; }else{ $skip = 0; } //レコード取得件数の指定 ※2 $max = 10; //FileMakerに接続 $fm = new FileMaker(); $fm->setProperty('database', 'Catalog'); $fm->setProperty('hostspec', 'http://localhost'); $fm->setProperty('username', 'web'); $fm->setProperty('password', 'pass'); //検索オブジェクトの作成 ※3 $findCommand =& $fm->newFindCommand('web_catalog'); //レコードの取得範囲の指定。※4 $findCommand->setRange($skip,$max);
- レコードの取得開始番号を指定します。検索条件の引き継ぎなどで、URLでのskipの指定がない場合は、番号を0にして最初のレコードから取得するようにします。
- 1度に取得するレコードの件数を指定します。ここでは10件を指定します。10件を超えるレコードの件数を取得した場合は、次ページなどのリンクを使って表示させるようにします。
FileMaker
クラスのnewFindCommand
を使って検索オブジェクトを作成します。引数にレイアウト名を渡します。- 検索オブジェクトの
setRange
メソッドを使って、取得するレコードの範囲を指定します。引数に開始位置と取得件数を指定します。
//検索条件の指定 ※5 if(!empty($_GET['ID'])){ $findCommand->addFindCriterion('ID','=='.$_GET['ID']); //※6 $search_query .= 'ID='.urlencode($_GET['ID']).'&'; } if(!empty($_GET['Name'])){ $findCommand->addFindCriterion('Name',$_GET['Name']); $search_query .= 'Name='.urlencode($_GET['Name']).'&'; } if(!empty($_GET['Genre_Name'])){ $findCommand->addFindCriterion( 'Genre::Genre_Name',$_GET['Genre_Name']); $search_query .= 'Genre_Name='.urlencode($_GET['Genre_Name']).'&'; } if(!empty($_GET['Maker_Name'])){ $findCommand->addFindCriterion( 'Maker::Maker_Name',$_GET['Maker_Name']); $search_query .= 'Maker_Name='.urlencode($_GET['Maker_Name']).'&'; } if(!empty($_GET['RegistDate'])){ //検索条件の対象が日付フィールドの場合は、 //日付の形式をmm/dd/yyyyに変換。※7 $registdate = date('m/d/Y', strtotime($_GET['RegistDate'])); $findCommand->addFindCriterion('RegistDate',$registdate); $search_query .= 'RegistDate='.urlencode($_GET['RegistDate']).'&'; } $findCommand->addSortRule('ID',1,FILEMAKER_SORT_ASCEND); //※8 //検索実行 ※9 $result = $findCommand->execute(); //検索実行後の処理。結果オブジェクト($result)が //エラーオブジェクトかどうかを判断する。※10 if(FileMaker::isError($result)){ //エラーコード、メッセージを取得。 $error_cd = $result->code; $error_mes = $result->getMessage(); }else{ //検索結果が得られた時の処理 ※11 //対象レコード数をセット $foundCount = $result->getFoundSetCount(); //取得したレコード数をセット $fetchCount = $result->getFetchCount(); //取得したレコードの開始番号を取得 $range_start = $skip+1; //取得したレコードの終了番号を取得 $range_end = $skip + $fetchCount; //レコードデータの取得 $records = $result->getRecords(); } ?>
- 検索オブジェクトの
addFindCriterion
メソッドを使って検索条件を指定します。引数にフィールド名と検索条件を渡します。ここでは、検索結果が多数ある場合に「前/次ページへのリンク」を利用するため、検索条件を引き継げるように$search_query
にフィールド名と検索条件の組み合わせをセットします。 - 送信する値にFileMakerで使用する検索演算子を付与することによって、FileMakerと同様に、完全一致検索や範囲指定などの検索オプションを適用することができます。
- 検索対象のフィールドが日付の場合、日付の書式はmm/dd/yyyyである必要があります。mm/ddで入力されていたり、yyyy/mm/ddとユーザーが入力する場合が多いので、PHPの
strtotime
関数を使って書式をmm/dd/yyyyに変換してセットするようにします。 - 検索オブジェクトの
addSortRule
メソッドを使って検索結果のレコードのソート順を指定します。引数には、ソートするフィールド名、複数のフィールドを指定する場合のソート優先順位、ソート方法を指定します。ソート方法は、昇順なら「FILEMAKER_SORT_ASCEND」、降順なら「FILEMAKER_SORT_DESCEND」、値一覧で指定した並び順として値一覧名を指定することができます。 - 検索オブジェクトの
execute
メソッドを使って検索を実行します。検索結果は結果オブジェクトとして$result
に返ってきます。 - 検索実行時、検索結果がないなどのエラーが発生した場合、結果オブジェクトの
$result
にはエラーオブジェクトが返ってきています。結果オブジェクトがエラーオブジェクトであるかどうか判断することで処理が正常に行われたかどうかが判断できます。エラーが発生した場合、エラーオブジェクトのgetMessage
メソッドを使ってエラーメッセージを取得します。 - 検索結果が得られた場合、結果オブジェクトの
getFoundSetCount
やgetFetchCount
メソッドを使って、対象件数や取得件数を取得します。開始番号の$skip
や取得件数の$max
を組み合わせて、表示するレコードの開始番号や終了番号などを取得します。検索結果のレコードは、getRecords
メソッドを使って取得します。取得したレコードはレコードオブジェクトの配列として$records
に取得することができます。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>検索結果一覧</title> </head> <body> <h1>検索結果一覧</h1> <?php //対象レコードがある場合の処理 ※12 if($foundCount){ ?> <p>検索結果<?=$foundCount?>件のうち、 <?=$range_start?>件目から<?=$range_end?>件目を表示しています。</p> <table border="1"> <tr> <th>商品ID</th> <th>商品名</th> <th>ジャンル</th> <th>メーカー</th> <th>価格</th> <th>登録日</th> </tr> <?php //取得したレコードを展開。※13 foreach($records as $record){ ?> <tr> <td><a href="detail.php?recid=<?=$record->getRecordId()?>&search_query=<?=urlencode($search_query.'skip='.$skip)?>"> <?=$record->getField('ID')?></a></td> <td><?=$record->getField('Name')?></td> <td><?=$record->getField('Genre::Genre_Name')?></td> <td><?=$record->getField('Maker::Maker_Name')?></td> <td><?php $price = $record->getField('Price'); if(is_numeric($price)){ echo number_format($price); }else{ echo $price; } ?> </td> <td><?=date('Y/m/d' , strtotime($record->getField('RegistDate')))?></td> </tr> <?php } ?> </table> <p> <?php //前・次ページへのリンクを表示。※14 //開始番号が、ページ表示件数より大きい場合は、 //前ページへのリンクを表示 if($range_start > $max){ echo '<a href="result.php?'.$search_query. '&skip='.($skip-$max).'">前のページ</a> '; } //終了番号よりも、対象件数が大きい場合は、 //次ページへのリンクを表示 if($range_end < $foundCount){ echo '<a href="result.php?'.$search_query. '&skip='.($skip+$max).'">次のページ</a>'; } ?> </p> <?php }else{ //対象レコードがない場合、エラーメッセージの表示 ※15 echo '<p>'.$error_mes.'('.$error_cd.')</p>'; } ?> <p><a href="search.php">検索フォームに戻る</a></p> <?=$registdate?> </body> </html>
- 対象レコードがある場合は、レコードを表示する処理を行い、ない場合はエラーメッセージを表示するようにします。対象レコードがある場合、取得したレコードの対象件数、表示するレコードの開始番号や終了番号を表示するようにします。
- 取得したレコードを
foreach
関数を使って展開します。$record
にはレコードオブジェクトが返ってきていますので、フィールドの値を表示させたい場合、getField
メソッドを利用します。数字の書式を整形する場合はPHPのnumber_format
関数、日付の書式を指定して表示したい場合は、strtotime
関数とdate
関数を利用して任意の書式で表示することができます。商品IDの表示のところには詳細ページへのリンクを設け、レコードIDを渡すようにしています。また、このリンクには検索条件と現在の取得開始番号も渡すようにしています。先の詳細画面からこの検索結果一覧に戻ってこれるようにするためです。 - 対象レコードが取得件数よりも多い場合は、「前/次ページのリンク」を表示するようにします。開始番号(
$range_start
)が取得件数($max
)よりも多い場合は、前ページのリンクを表示させます。リンクには、5でセットした検索条件を渡し、開始番号を前のページにセット($skip-$max
)します。終了番号よりも対象件数が多い場合は、次のページのリンクを表示させるようにします。次のページのリンクには、前ページのリンク同様、次ページに合わせた値($skip+$max
)を検索条件と開始番号にセットします。 - エラーが発生した場合(対象レコードがないなど)、ここで取得したエラーメッセージを表示させます。