FX.phpとFileMaker API for PHPの機能比較として、登録と検索を紹介してきた。機能面を除くと、いまのところサーバにかかる負荷の少なさやパフォーマンスの伸びはFX.phpが上といったところ。今回からはレコード編集について機能比較をしていこう。

レコードの編集方法 - FX.php / API での違い

まずはレコードの編集~返り値の相違点をチェックだ。

  FX.php API 備考
フィールド設定 AddDBParam setField, setFieldFromTimestamp, createRecord FX.phpにはsetFieldFromTimestampに相当する機能がない
レコードID指定 SetRecordID('レコードID') newEditCommandの第二引数, FileMaker_Command_Editコンストラクタの第三引数, setRecordID('レコードID')  
修正ID指定 SetModID('修正ID') setModificationId('修正ID')  
リクエスト発行 FMEdit, DoFXAction('edit') execute, commit  
返り値のタイプ 配列 object FileMaker_Result, object FileMaker_Error, boolean true FX.phpで同時取得できるのは空欄不可・繰り返し数・フィールドタイプの3点で、ほかのオプション情報は取得できない。APIでは各種結果を取り出すのに各メソッドを使う必要あり

レコードの編集処理には以前から紹介しているとおり、レコードIDの指定が必須。またオプションではあるが、排他処理のために修正IDも指定しておくにこしたことはないだろう。レコードIDはFX.phpではSetRecordIDかAddDBParamのどちらかで指定する。APIではsetRecordIDをつかうほか、FileMaker_Command_Editオブジェクトを作成する際に引数として渡すことも可能だ。

リクエストを発行する場合、FX.phpでは専用のメソッドを使用する必要がある。APIでは登録や検索と同様、executeとcommitでOKだ。

FX.phpでレコードを編集、結果を取得するまでの手順

  1. new FXでインスタンスを作成、接続先を指定
  2. AddDBParamでフィールドに登録したい内容を指定
  3. SetRecordIDで編集したいレコードIDを指定
  4. SetModIDで編集したいレコードの修正IDを指定
  5. FMEditまたはDoFXAction('edit')でリクエスト発行
  6. 結果を配列で取得
  7. $resultSet['errorCode']の値でエラー判定
  8. $resultSet['data']からフィールド内容を取得

APIでレコードを編集、結果を取得するまでの手順

  1. new FileMakerでFileMakerのインスタンスを作成、接続先を指定
  2. newEditCommandでFileMakerCommandEditオブジェクトを作成。この際にレイアウトと編集したいレコードIDを指定
  3. setField, setFieldFromTimestampでフィールドに登録したい内容を指定
  4. setModificationIdで編集したいレコードの修正IDを指定
  5. executeでリクエスト発行
  6. 成功した場合はFileMaker_Resultオブジェクトが、失敗した場合はFileMaker_Errorオブジェクトが返る
  7. FileMaker::isErrorでエラー判定
  8. getFirstRecordやgetRecordsでFileMaker_Recordオブジェクトを取得
  9. getFieldやgetFieldUnencodedでフィールド内容を取得

それでは実際に動作するサンプルを書いてみる。登録同様、フィールド2つに対して値をセットしてレコードを編集、レイアウトに配置されているフィールド内容の結果を表示する。

FileMaker DB情報 名前
ファイル名 fmapi_test.fp7
テーブル名 fmapi_table
レイアウト名 fmapi_list

FX.phpの場合 - fx_edit.php

<?php

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

// 文字列エスケープ用関数
function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}

// 1. FXインスタンスを作成、接続先を指定
$data = new FX('localhost', 80, 'FMPro9', 'http');
$data->SetDBData('fmapi_test','fmapi_list');
$data->SetDBUserPass('admin','admin');

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

// 2. AddDBParamでフィールドに登録したい内容を指定
$data->AddDBParam('ft_text', 'fx_edit.phpよりレコード編集');
$data->AddDBParam('ft_date', date('m/d/Y'));

// 3. SetRecordIDで編集したいレコードIDを指定
$data->SetRecordID(1);

// 4 SetModIDで編集したいレコードの修正IDを指定
$data->SetModID(1);

// 5. FMEditまたはDoFXAction('edit')でリクエスト発行
// 6. 結果を配列で取得
$resultSet = $data->FMEdit();
// $resultSet = $data->DoFXAction('edit'); でも可

// 7. $resultSet['errorCode']の値でエラー判定
if ( 0 === (int)$resultSet['errorCode'] )
{
    // 8. $resultSet['data']からフィールド内容を取得
    echo '<table border="1">';
    foreach( $resultSet['data'] as $recordValue )
    {
        foreach( $data->lastFields as $fieldValue )
        {
            echo '<tr>';
            echo '<th>' . $fieldValue['name'] . '</th>';
            echo '<td>' . h($recordValue[$fieldValue['name']][0]) . '&nbsp;</td>';
            echo '</tr>';
        }
        unset($fieldValue);
    }
    unset($recordValue);
    echo '</table>';
}
else
{
    // エラー処理
    echo '<table border="1">';
    echo '<tr>';
    echo '<th>FileMakerエラーコード</th>';
    echo '<td>' . $resultSet['errorCode'] . '</td>';
    echo '</tr>';
    echo '<tr>';
    echo '<th>エラー内容</th>';
    echo '<td>' . $errorsList[$resultSet['errorCode']] . '</td>';
    echo '</tr>';
    echo '</table>';
}
?>

APIの場合 - api_edit.php

<?php

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

// 文字列エスケープ用関数
function h($string)
{
    return htmlspecialchars(trim($string), ENT_QUOTES, 'UTF-8');
}

// 1. new FileMakerでFileMakerのインスタンスを作成、接続先を指定
$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');

// 2. newEditCommandでFileMaker_Command_Addオブジェクトを作成
//    この際にレイアウトと編集したいレコードIDを指定
$editCommand = $data->newEditCommand('fmapi_list', 1);

// 3. setField, setFieldFromTimestampでフィールドに登録したい内容を指定
$editCommand->setField('ft_text', 'api_edit.phpよりレコード編集');
$editCommand->setField('ft_date', date('m/d/Y'));
//$editCommand->setFieldFromTimestamp('ft_date', mktime(0,0,0, date('m'), date('d'), date('Y')));

// 4. setModificationIdで編集したいレコードの修正IDを指定
$editCommand->setModificationId(1);

// 5. executeでリクエスト発行
// 6. 成功した場合はFileMaker_Resultオブジェクトが、失敗した場合はFileMaker_Errorオブジェクトが返る
$resultSet = $editCommand->execute();

// 7. FileMaker::isErrorでエラー判定
if (!FileMaker::isError($resultSet))
{
    // 8. getFirstRecordやgetRecordsでFileMaker_Recordオブジェクトを取得
    echo '<table border="1">';
    foreach ( $resultSet->getRecords() as $record )
    {
        foreach( $record->getFields() as $fieldName )
        {
            // 9. getFieldやgetFieldUnencodedでフィールド内容を取得
            echo '<tr>';
            echo '<th>' . $fieldName . '</th>';
            echo '<td>' . h($record->getFieldUnencoded($fieldName)) . '&nbsp;</td>';
            echo '</tr>';
        }
        unset($fieldValue);
    }
    echo '</table>';
}
else
{
    // エラー処理
    echo '<table border="1">';
    echo '<tr>';
    echo '<th>FileMakerエラーコード</th>';
    echo '<td>' . $resultSet->getCode() . '</td>';
    echo '</tr>';
    echo '<tr>';
    echo '<th>エラー内容</th>';
    echo '<td>' . $resultSet->getMessage() . '</td>';
    echo '</tr>';
    echo '</table>';
}
?>

編集したいフィールドは「ft_text」と「ft_date」。編集処理に成功した場合は、フィールド名とフィールド内容をテーブルで表示する。なお、なぜか筆者の環境ではsetFieldFromTimestampが正常に動作しなかった(フィールド名が渡されず、Field Not Foundとなる)ので、setFieldで代用した。実装のコア部分であるAddImpl.php 61-80行目とEditImpl.php 82-100行目を確認してみたところ、使用している変数が違っているように思える。難読化されている所為で詳しくは追い切れなかったが、このあたりの事情について知っている方はぜひご教示いただきたい。

実際にWebブラウザで動作を確認してみる。

fx_edit.phpにアクセスしてレコードを編集。レコード情報の表示方法は登録同様、自動生成

修正IDを指定するようにしていると、同時アクセスがあった場合でも競合を防ぐことができる

api_edit.phpにアクセスしてレコードを編集。

setFieldFromTimestampを使用すると、なぜかField Not Foundエラーがでてしまう

登録処理と違うのは、レコードIDと修正IDを指定しているくらいか。こまかい違いとして、APIではcommit()がある分、おなじレコードの連続編集がやりやすいというメリットがある。FileMaker側でルックアップや計算値の自動入力等を多用しておなじレコードに2回以上レコードにアクセス・編集する必要がある場合は、APIの方が使いやすいだろう。