前回に引きつづき、レコードの検索処理について取りあげよう。今回はFileMaker API for PHPを利用する上でかならず押さえておきたい機能「複合検索の実装方法」を紹介する。

複合検索に使用する2つのクラス

前回紹介した3つの検索機能――「検索(-find)」「全件表示(-findall)」「ランダムに1件表示(-findany)」は、FX.phpにおいても同様の機能を実現可能だ。今回はAPI for PHPを利用した場合にのみ実現できる「複合検索の実装方法」にて使用するクラスとメソッドの使い方を紹介しよう。今回おもに紹介するクラスは、前回紹介できなかった「FileMaker_Command_FindRequest」と、関連する「FileMaker_Command_CompoundFind」の2つだ。

FileMaker_Command_FindRequest

複合検索をおこなう場合の、1検索条件を作成するために使用するクラス。複数の検索条件がある場合は、その分のインスタンスを作成することになる。

FileMaker_Command_CompoundFind

実際に複合検索をおこなうためのクラス。FileMaker_Command_FindRequestクラスを使用して作成した検索条件のセットを指定し、ソート条件や実行したいFileMakerスクリプトを指定後、検索をおこなう。

複合検索はおもにこの2クラスを使用しておこなうことになる。おおまかな手順は次のとおり。

  1. newFindRequestで作成したい検索条件分のインスタンス(FileMaker_Command_FindRequest)を作成
  2. addFindCriterionやsetOmitで検索条件を指定
  3. newCompoundFindCommandで検索条件のセットをまとめるためのインスタンス(FileMaker_Command_CompoundFind)を作成
  4. 3で作成したオブジェクトにaddを使用して、1~2で作成した検索条件のセットを格納
  5. レンジ設定やソート条件、検索時に実行したいFileMakerスクリプトなどを指定
  6. 3-5で作成したオブジェクトを使用して、検索を実行

2つのオブジェクトをFileMakerの画面と合わせたイメージ図。newFindRequestでn個の検索条件オブジェクト(FileMaker_Command_FindRequest)を作成し、FileMaker_Command_CompoundFindでそれらをまとめ、検索をおこなう

検索条件の作成~複合検索実行までの流れ

前回同様、fmapi_listレイアウトを使用して実際に複合検索をおこなってみよう。fmapi_listレイアウトには、10レコードが登録されている。

fmapi_listに登録されているレコード

今回複合検索で使用する検索条件は次のとおり。

  1. ft_registTimeStampが2009/8/18 *:*:*かつ、ft_numが10,000より小さい
  2. ft_textが「テスト文字列」かつ、ft_numが1,000から10,000の間の値であること
  3. ft_dateが2009/09/*かつ、ft_numが5000より大きい

それではこの3つの検索条件をコードにしてみよう。

fmapi_find_test2.php

<?php

include_once('../FileMaker.php');

$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');

$findRequest = array();

$findRequest[0] = $data->newFindRequest('fmapi_list');
$findRequest[0]->addFindCriterion('ft_registTimeStamp', '8/18/2009 *:*:*');
$findRequest[0]->addFindCriterion('ft_num', '<10000');

$findRequest[1] = $data->newFindRequest('fmapi_list');
$findRequest[1]->addFindCriterion('ft_text', 'テスト文字列');
$findRequest[1]->addFindCriterion('ft_num', '1000...10000');

$findRequest[2] = $data->newFindRequest('fmapi_list');
$findRequest[2]->addFindCriterion('ft_date', '9/*/2009');
$findRequest[2]->addFindCriterion('ft_num', '>5000');

$compoundFind = $data->newCompoundFindCommand('fmapi_list');
$compoundFind->add(1, $findRequest[0]);
$compoundFind->add(2, $findRequest[1]);
$compoundFind->add(3, $findRequest[2]);

$compoundFind->setRange(0, 10);

$result = $compoundFind->execute();

if (FileMaker::isError($result))
{
    // エラー処理..
    echo 'FileMaker Error Code: ' . $result->getCode();
    echo '<p>'. $result->getMessage() . '</p>';
}
else
{
    // 正常処理..
    $records = $result->getRecords();
    ?>
    <table border="1">
        <tr>
            <th>ft_serial</th>
            <th>ft_registTimeStamp</th>
            <th>ft_updateTimeStamp</th>
            <th>ft_text</th>
            <th>ft_date</th>
            <th>ft_num</th>
        </tr>
    <?php
    foreach ($records as $record)
    {
        echo '<tr>';
        echo '<td>' . $record->getField('ft_serial') . '</td>';
        echo '<td>' . $record->getField('ft_registTimeStamp') . '</td>';
        echo '<td>' . $record->getField('ft_updateTimeStamp'). '</td>';
        echo '<td>' . $record->getField('ft_text'). '</td>';
        echo '<td>' . $record->getField('ft_date'). '</td>';
        echo '<td>' . $record->getField('ft_num'). '</td>';
        echo '</tr>';
    }
    ?>
    </table>
    <?php
}

?>

この複合検索のイメージ図は次のとおり。

1つの検索条件につき、1つのFileMaker_Command_FindRequestオブジェクトが割りあてられる。今回は3つの検索条件があるため、オブジェクト数も3つ。3つのFileMaker_Command_FindRequestオブジェクトをFileMaker_Command_CompoundFindオブジェクトに格納し、検索を実行

$findRequestを配列とし、$findRequest[0]から$findRequest[2]までそれぞれの検索条件を作成。$compoundFindに作成した検索条件をまとめて複合検索を実行している。これをWebブラウザで表示する。

3つの複合検索条件に一致するレコードが表示された

同様の複合検索をFileMaker上でおこなった結果。間違いのないことが確認できる

ほかの検索の方法と比較するとすこしだけ複雑だが、無事に複合検索を実現することができた。FileMaker上で実際におこなった検索と比較しても差がないことから、問題なく複合検索が実装できていることが確認できる。

関連メソッドの紹介

まずはFileMaker_Command_FindRequestで使用するメソッドだ。

addFindCriterionメソッド (FindRequest.php 59-65行目より)

    /**
     * Add a find criterion.
     *
     * @param string $fieldname The field being tested.
     * @param string $testvalue The value to test against.
     */
    function addFindCriterion($fieldname, $testvalue)
  • string $fieldname: フィールド名を指定
  • string $testvalue: 検索内容を指定

フィールドと検索内容を対にして検索条件を指定する。前回紹介したaddFindCriterionと同じ動作をおこなう。

clearFindCriteriaメソッド (FindRequest.php 70-73行目より)

    /**
     * Clear all existing find criteria.
     */
    function clearFindCriteria()

このメソッドに引数はない。addFindCriterionで指定した検索条件をすべて削除する。

setOmitメソッド (FindRequest.php 49-54行目より)

    /**
     * Sets if the find request is an omit request.
     *
     * @param boolean $value true or false.
     */
    function setOmit($value)
  • boolean $value: 入力した検索条件を除外とするかを指定する

$valueにtrueを指定すると、その検索条件を除外して検索結果を取得する。

setOmit(true)を指定したFindRequestオブジェクトは、FileMakerで言う「除外」にチェックが入った状態の検索条件となる

つづけてFileMaker_Command_CompoundFindクラスのメソッドを紹介しよう。

addメソッド (CompoundFind.php 49-55行目より)

     /**
     * Add a find request to the find set.
     *
     * @param int $precedence defines the priority in which the find requests are added to the set.
     * @param findrequest $findrequest is the find request being added to the compound find set. 
     */
    function add($precedence, $findrequest)
  • int $precedence: 指定する検索条件セットの優先度を指定する
  • object $findrequest: 検索条件セットを設定したFileMaker_Command_FindRequestオブジェクトを指定する

複合検索の実装の要、複数の検索条件セットを指定するメソッド。当然ながら一度におおくの検索条件セットを指定すると、サーバに負荷がかかり動作が重くなるので注意が必要だ。

addSortRuleメソッド (CompoundFind.php 60-67行目より)

     /**
     * Add a sorting rule to the find request.
     *
     * @param string $fieldname The field to sort by.
     * @param integer $precedence 1-9, should we sort by this field first, last, etc.
     * @param mixed $order FILEMAKER_SORT_ASCEND, FILEMAKER_SORT_DESCEND, or a custom value list.
     */
    function addSortRule($fieldname, $precedence, $order = null)
  • string $fieldname: ソートをおこないたいフィールド名を指定
  • integer $precedence: ソートの優先順位を1から9の範囲で指定する
  • mixed $order: ソート順を指定する。ソート順は「昇順」「降順」「値一覧に基づく順位」の中から指定する

clearSortRulesメソッド (CompoundFind.php 72-75行目より)

    /**
     * Clear all existing sorting rules.
     */
    function clearSortRules()

このメソッドに引数はない。addSortRuleで指定したソート条件をすべて削除する。

getRangeメソッド (CompoundFind.php 91-99行目より)

    /**
     * Return the current range settings.
     *
     * @return array An associative array with two keys: 'skip' for
     * the current skip setting, and 'max' for the current maximum
     * number of records. If either key does not have a value it will
     * be set to NULL.
     */
    function getRange()

このメソッドに引数はない。現在指定されているレンジ設定($skip, $max)を配列で取得する。

setRangeメソッド (CompoundFind.php 80-87行目より)

 /**
     * Request only part of the result set.
     *
     * @param integer $skip The number of records to skip past.
     * @param integer $max The maximum number of records to return.
     */
    function setRange($skip = 0, $max = null)
  • integer $skip: 先頭からかぞえて除外するレコード数を指定。省略した場合は0が格納される
  • integer $max: 一度に取得するレコード数上限を指定。省略した場合はnullが格納される

addSortRule, clearSortRules, getRange, setRangeは前回紹介したメソッドとおなじ動作をすると考えて良いだろう。いままでの検索と違う点は、addFindCriterionで検索条件を指定するのではなく、addを使って検索条件のセットを指定するところだ。このほか、FileMaker_Commandより次のメソッドも継承する。

  • execute()
  • setPreCommandScript()
  • setPreSortScript()
  • setRecordClass()
  • setRecordId()
  • setResultLayout()
  • setScript()
  • validate()

用途については前回の最後の部分を参照してほしい。

今回は、FileMaker API for PHPを使用した複合検索の実装方法を紹介した。このような複合検索をFX.phpでおこなうには、いまのところ-queryと-findqueryをうまく用いて実装するか、それぞれの検索結果が格納された配列を自力でマージするといった方法しかない。それと比較すると、かなり簡単にあつかえるようになっていると言えるのではないだろうか。FileMaker API for PHPを使う場合は、かならず押さえておきたい機能だ。