FX.php、FileMaker API for PHPの基本操作からパフォーマンス比較、そしてFMCakeMixの基本操作チュートリアルを紹介してきた。前回より、FX.phpで複合検索をおこなう方法に、-findquery/-queryの構造を簡単に紹介した。今回は-findquery/-queryを使った複合検索の、FX.phpでのコーディングについて取りあげよう。

FX.phpで複合検索をおこなうには - FX.phpでの実装

-findqueryと-queryを使って、実際にFX.phpで複合検索を実装してみよう。 FileMakerファイル情報は次のとおり。

  • ファイル名: fxphp_tips.fp7
  • テーブル名: gelende
  • レイアウト名: 複合検索テスト_ゲレンデ情報
  • フィールド: 別表、別図参照
フィールド名 コメント タイプ オプション
serial シリアルナンバ 数字 番号自動入力, ユニークな値
registTimeStamp 登録日時 タイムスタンプ 作成タイムスタンプ
updateTimeStamp 更新日時 タイムスタンプ 修正タイムスタンプ
name ゲレンデ名 テキスト  
uri URI テキスト  
address 住所 テキスト  
length 最大滑走距離 数字  
maxAngle 最大斜度 数字  

作成したフィールド一覧

フィールドで管理する情報

このデータベースでは、関東圏近郊のスキー・スノーボードゲレンデの一部の情報を管理している

このサンプルデータベースでは、スキー・スノーボードゲレンデの情報を管理している。住所や最大滑走距離、最大斜度を使って複合検索条件をためしに作成してみる。

たとえば「群馬県内の、最大滑走距離が3000以上または最大斜度が30以上」のゲレンデを絞り込んで表示してみよう。

検索条件

  • 1番目の検索条件: フィールド「address」に&quot群馬"がふくまれているかつ、フィールド「length」が"3000"以上であること
  • 2番目の検索条件: フィールド「address」に&quot群馬"がふくまれているかつ、フィールド「maxAngle」が"30"以上であること

前回の順番に沿って、クエリを組み立てる。

  1. クエリIDとFileMakerフィールド名を紐付け
  2. クエリIDに検索したい文字列を指定
  3. クエリIDを使用して、検索条件を組み立てる

クエリIDとFileMakerフィールド名を紐付け

まずクエリIDとFileMakerフィールド名を紐づける。今回の複合検索条件の場合だと、使用するクエリID数は3つ。

  • -q1: address
  • -q2: length
  • -q3: maxAngle

このクエリを連結すると、次の文字列になる。

-q1=address&-q2=length&-q3=maxAngle

クエリIDに検索したい文字列を指定

続いて、クエリIDに検索したい文字列を指定する。

  • -q1.value: 群馬
  • -q2.value: >=3000
  • -q3.value: >=30

ここでは演算子"gte"を使わず、直接">="を検索条件にもちいる。このクエリを連結すると、次の文字列になる。

-q1.value=群馬&-q2.value=>=3000&-q3.value=>=30

クエリIDを使用して、検索条件を組み立てる

最後に、-queryクエリパラメータでクエリIDを指定して、検索条件を組み立てる。

-query=(q1,q2);(q1,q3)

これらのクエリを連結して検索リクエストを発行すると次の構文となる。

-q1=address&-q2=length&-q3=maxAngle&
-q1.value=群馬&-q2.value=>=3000&-q3.value=>=30&
-query=(q1,q2);(q1,q3)&
-findquery

このクエリはFileMaker Proで検索をおこなう場合、次の検索条件と同様の意味となる。

上記複合検索条件をFileMaker Pro上で再現した場合

FX.phpを使った実装例は次のとおり。

FX.php修正箇所 - 75行目付近

var $actionArray = array(
        // for backwards compatibility
        "-delete"               =>"-delete",
        "-dup"                  =>"-dup",
        "-edit"                 =>"-edit",
        "-find"                 =>"-find",
        "-findall"              =>"-findall",
        "-findany"              =>"-findany",
        "-new"                  =>"-new",
        "-view"                 =>"-view",
        "-dbnames"              =>"-dbnames",
        "-layoutnames"          =>"-layoutnames",
        "-scriptnames"          =>"-scriptnames",
        "-sqlquery"             =>"-sqlquery",
        // new params for DoFXAction
        "delete"                =>"-delete",
        "duplicate"             =>"-dup",
        "update"                =>"-edit",
        "perform_find"          =>"-find",
        "show_all"              =>"-findall",
        "show_any"              =>"-findany",
        "new"                   =>"-new",
        "view_layout_objects"   =>"-view",
        "view_database_names"   =>"-dbnames",
        "view_layout_names"     =>"-layoutnames",
        "view_script_names"     =>"-scriptnames",
        "-findquery"            =>"-findquery"
    );

最初にFX.phpの$actionArrayの最下部に、-findqueryの1行を追加している。これは、FX.phpのDoFXActionで-findqueryをリクエストできるようにするためのもの。

FX.php 複合検索サンプル - fx_compoundFind.php

<?php
include_once('../fx/FX.php');
include_once('../fx/FX_Fuzzy_Debugger.php');

$data = new FX('localhost', 80, 'FMPro9', 'http');

$data->SetDBData('fxphp_tips.fp7','複合検索テスト_ゲレンデ情報');
$data->SetDBUserPass('admin','');

$data->SetCharacterEncoding('utf8');
$data->SetDataParamsEncoding('utf8');

// 1. クエリIDとFileMakerフィールド名を紐付け
$data->AddDBParam('-q1', 'address');
$data->AddDBParam('-q2', 'length');
$data->AddDBParam('-q3', 'maxAngle');

// 2. クエリIDに検索したい文字列を指定 
$data->AddDBParam('-q1.value', '群馬');
$data->AddDBParam('-q2.value', '>=3000');
$data->AddDBParam('-q3.value', '>=30');

// 3. クエリIDを使用して、検索条件を組み立てる
$data->AddDBParam('-query', '(q1,q2);(q1,q3)');

// 検索実行
$result = $data->DoFXAction('-findquery', true, true, 'full');

?>
<table>
    <tr>
        <th>
            serial
        </th>
        <th>
            ゲレンデ名
        </th>
        <th>
            住所
        </th>
        <th>
            最大滑走距離
        </th>
        <th>
            最大斜度
        </th>
    </tr>
<?php
foreach ($result['data'] as $key => $record)
{
    ?>
    <tr>
        <td>
            <?php echo $record['serial'][0]; ?>
        </td>
        <td>
            <?php echo $record['name'][0]; ?>
        </td>
        <td>
            <?php echo $record['address'][0]; ?>
        </td>
        <td>
            <?php echo number_format($record['length'][0]); ?>m
        </td>
        <td>
            <?php echo $record['maxAngle'][0]; ?>
        </td>
    </tr>
    <?php
}
?>

クエリIDの指定やクエリの構築には、AddDBParamをもちいる。

// 1. クエリIDとFileMakerフィールド名を紐付け
$data->AddDBParam('-q1', 'address');
$data->AddDBParam('-q2', 'length');
$data->AddDBParam('-q3', 'maxAngle');

// 2. クエリIDに検索したい文字列を指定 
$data->AddDBParam('-q1.value', '群馬');
$data->AddDBParam('-q2.value', '>=3000');
$data->AddDBParam('-q3.value', '>=30');

// 3. クエリIDを使用して、検索条件を組み立てる
$data->AddDBParam('-query', '(q1,q2);(q1,q3)');

-findqueryはFMFind()やFMFindAny()のように、専用のメソッドが用意されていないのでDoFXActionで代用する。

$result = $data->DoFXAction('-findquery', true, true, 'full');

これで$resultに結果セットが返るので、foreachで検索に該当したレコードを展開する。Webブラウザでfx_compoundFind.phpを確認してみよう。

FileMaker Proでさきほどの複合検索をおこなった結果。このデータ内での該当は9件

Webブラウザでfx_compoundFind.phpを表示。FileMaker Pro上でおこなった検索と同じ結果がWebブラウザで表示でき、FX.phpで複合検索が実装できていることがわかる

ひとつ気をつけたいのは、-findqueryをもちいた場合、-query以外の検索クエリは無視されるということ。たとえば今回のサンプルの場合、「住所が群馬であること」というのは共通の検索条件。この場合

$data->AddDBParam('address', '群馬');
$data->AddDBParam('-q1', 'length');
$data->AddDBParam('-q2', 'maxAngle');
$data->AddDBParam('-q1.value', '>=3000');
$data->AddDBParam('-q2.value', '>=30');
$data->AddDBParam('-query', '(q1);(q2)');
$result = $data->DoFXAction('-findquery', true, true, 'full');

と書きたくなるところだが、この構文ではうまく動作しないので注意されたい。FX.phpで-query/-findqueryをもちいた検索では、これまで紹介してきたものと若干性質が異なる動作をする。いくつも検索パターンを試し、動作する/動作しないの確認をとっておきたいところだ。