FX.phpとFileMaker API for PHPの機能比較として、登録と検索・編集を紹介してきた。のこりレコードの削除と、スクリプトの実行方法について解説していこう。まずはレコード削除からだ。

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

レコードの削除実行~返り値の相違点をチェックする。

  FX.php API 備考
レコードID指定 SetRecordID('レコードID') newDeleteCommandの第二引数, FileMaker_Command_Deleteコンストラクタの第三引数, setRecordID('レコードID')  
リクエスト発行 FMDelete, DoFXAction('delete') execute  
返り値のタイプ boolean true, 配列 object FileMaker_Result, object FileMaker_Error, boolean true FX.phpのFMDeleteでは成功/失敗に関係なくtrueが返る(FMDeleteに引数を渡すことで、いままでどおり配列として取得することも可)

レコードの削除処理も編集処理と同様、レコードIDの指定が必須。ただしレコード修正IDの指定には対応していない。

この削除処理のみ、FX.phpのFMDeleteではほかの処理と動作が違うので注意が必要だ。登録(FMNew)・検索(FMFind)・編集(FMEdit)は配列で結果を返すが、削除(FMDelete)の場合のみ結果をboolean値を返す。しかもオプションを指定しないと、成功・失敗に関わらずtrueを返す。これは内部の実装において、FMDeleteのデフォルト引数「$returnDataSet」がfalseとなっているためだ。

function FMDelete - FX.php 1,909-1,912行目より

function FMDelete ($returnDataSet = false, $returnData = 'basic', $useInnerArray = true)
{
    return $this->FMAction("-delete", $returnDataSet, $returnData, $useInnerArray);
}

function FMAction - FX.php 1,689-1,706行目より

function FMAction ($Action, $returnDataSet, $returnData, $useInnerArray)
{
    $this->useInnerArray = $useInnerArray;
    $queryResult = $this->ExecuteQuery($this->actionArray[strtolower($Action)]);
    if (FX::isError($queryResult)){
        if (EMAIL_ERROR_MESSAGES) {
            EmailErrorHandler($queryResult);
        }
        return $queryResult;
    }
    if ($returnDataSet) {
        $dataSet = $this->AssembleDataSet($returnData);
        return $dataSet;
    } else {
        $this->ClearAllParams();
        return true;
    }
}

オプションを指定しないでFMDeleteを使用した場合、たとえば存在しないレコードIDを指定してもtrueが返ってしまう。なお、DoFXActionはデフォルト引数「$returnDataSet」がtrueで実行されるため、FileMaker側のエラーコードを取得できる。エラー処理をきちんと実装する場合は、FMDelete(true)かDoFXAction('delete')を使うようにしよう。

function DoFXAction - FX.php 1,964-1,968行目より

// DoFXAction() is a general purpose action function designed to streamline FX.php code
function DoFXAction ($currentAction, $returnDataSet = true, $useInnerArray = false, $returnType = 'object')
{
    return $this->FMAction($currentAction, $returnDataSet, $returnType, $useInnerArray);
}

それでは削除処理の実装方法に移る。

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

  1. new FXでインスタンスを作成、接続先を指定
  2. SetRecordIDで削除したいレコードIDを指定
  3. FMDelete(true)またはDoFXAction('delete')でリクエスト発行
  4. 結果を配列で取得
  5. $resultSet['errorCode']の値でエラー判定

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

  1. new FileMakerでFileMakerのインスタンスを作成、接続先を指定
  2. newDeleteCommandでFileMaker_Command_Deleteオブジェクトを作成。この際にレイアウトと削除したいレコードIDを指定
  3. executeでリクエスト発行
  4. 成功した場合はFileMaker_Resultオブジェクトが、失敗した場合はFileMaker_Errorオブジェクトが返る
  5. FileMaker::isErrorでエラー判定

FX.php/APIともにシンプルな構文で実装することが可能。サンプルは次のとおり。

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

FX.phpの場合 - fx_delete.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',1);
$data->SetDBUserPass('admin','admin');

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

// 2. SetRecordIDで削除したいレコードIDを指定
$data->SetRecordID(1);

// 3. FMDelete(true)またはDoFXAction('delete')でリクエスト発行
// 4. 結果を配列で取得
$resultSet = $data->FMDelete(true);
// $resultSet = $data->DoFXAction('delete'); でも可

// 5. $resultSet['errorCode']の値でエラー判定
if ( 0 === (int)$resultSet['errorCode'] )
{
    echo 'レコードの削除に成功';
}
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_delete.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. newDeleteCommandでFileMaker_Command_Deleteオブジェクトを作成
//    この際にレイアウトと削除したいレコードIDを指定
$deleteCommand = $data->newDeleteCommand('fmapi_list', 1);

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

// 5. FileMaker::isErrorでエラー判定
if (!FileMaker::isError($resultSet))
{
    echo 'レコードの削除に成功';
}
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>';
}
?>

レコード削除の場合はフィールド内容は返らないので、簡単なメッセージを表示するのみとした。実際にWebブラウザで動作を確認する。

それぞれの実行結果。上段がFX.php, 下段がAPIとなっている。FMDeleteでオプションを指定しないとこのようなエラー処理もできないので、使用する際はかならずオプションを指定するように心がけよう

注意点として修正IDの指定に対応していないため、「別ユーザが編集→それを知らず直後にレコード削除」といった流れがあり得る。これを防ぐには自前でレコードロックに相当する機能を作成するか、FileMakerスクリプトを利用するのが良いだろう。