FileMaker API for PHPでレコードの登録をおこなう方法を2回にわたり紹介した。今回は前回の最後に少しとりあげた事前検証処理(validate)について、もう少し深く掘りさげて取りあげよう。
validate()使用前に気をつけておくこと
まずはFileMaker_Command::validate()で検証できる・できない入力値の制限について確認しておこう。
validate()で事前検証が可能な入力値の制限
- 空欄不可
- タイプ: 数字
- 最大文字数
- タイプ: 西暦4桁の日付
- タイプ: 時刻
- 日付フィールド
- 時刻フィールド
- タイムスタンプフィールド
validate()で事前検証が不可能な入力値の制限
- ユニークな値
- 既存値
- 下限値, 上限値
- 値一覧名
- 計算式で制限
事前検証が不可能な入力値の制限はvalidate()ではどうやっても捕捉不可能だ。実際に登録・編集をおこなって初めて返ってくるエラーを使用して処理をおこなうか、ほかの手段を考えよう。
事前検証が不可能な入力値の制限で、検証をおこなう代案
- ユニークな値: 登録・編集処理前に該当フィールドに対してaddFindCriterion()後、exccute()。FileMaker::isError()がfalse(エラーなし)ならば、ユニークではないと判定
- 既存値: 登録・編集処理前に該当フィールドに対してaddFindCriterion()後、exccute()。FileMaker::isError()がtrueかつ、getCode()が401(レコードが見つからない)ならば、既存値ではないと判定
- 下限値, 上限値: 別途PHP側で定義し、独自エラー処理
- 値一覧名: listValueLists()で値一覧を取得し、入力された値が値一覧内にて定義されているかを検証する
- 計算式で制限: 別途PHP側で定義し、独自エラー処理
ほかに気をつけておきたいこととして、フィールドオプションの入力値の制限で設定する「タイプ: 西暦4桁の日付」「タイプ: 時刻」と、「日付フィールド」「時刻フィールド」は別扱いのバリデーションエラーとしてあつかわれることが挙げられる。
検証後に返るFileMaker_Error_Validationオブジェクトとは
validate()に失敗(登録する値が入力値の制限にひっかかり、エラーが発生した場合は、FileMaker_Error_Validationオブジェクトが返る。このオブジェクトにはおおくの情報がふくまれているが、大別するとおもに次の情報が格納されている。
- FileMaker_Implementation Object: FileMaker Serverに接続するための情報が格納
- FileMaker_Field_Implementation Object: レイアウトに配置されているフィールドの詳細な情報が格納。入力値の制限(_validationRules)はこのオブジェクト内に格納されている
- FileMaker_Command_Add_Implementation Object: 検証に使用したフィールドと値を格納
この中から各種メソッドを使用し、必要な情報を取りだしていくことになる。用意されているメソッドは次のとおり。
FileMaker_Error_Validationクラスに用意されているメソッド
- addError()
- getErrors()
- isValidationError()
- numErrors()
FileMaker_Errorクラスから継承するメソッド
- FileMaker_Error()
- getErrorString()
- getMessage()
- isValidationError()
addError()はおもに内部で使用されているメソッドだ。独自でvalidate()の追加検証を実装する場合をのぞけば、とくに使う必要はない。isValidationError()はオブジェクト判定用のメソッドだが、validate()実行後の返り値の都合上、FileMaker::isError()を使用するほうが融通がききやすい。よって、ここではおもにgetErrors()とnumErrors()の2メソッドを中心に取りあげよう。
getErrorsメソッド (Validation.php 70-88行目より)
/**
* Returns an array of arrays describing the validation errors
* that occurred. Each entry in the outer array represents an
* individual validation failure. Each failure is represented by a
* three-element array with the following members:
*
* 0 => The field object for the field that had the validation problem.
* 1 => The validation rule that failed for that field (a FILEMAKER_RULE_* constant).
* 2 => The invalid value.
*
* Multiple validation rules can fail on a single field. If the
* optional $fieldName parameter is set, then only failures for
* that individual field will be returned.
*
* @param string $fieldName Get errors only for this field name.
*
* @return array Validation error details.
*/
function getErrors($fieldName = null)
- string $fieldName: エラー情報を取得したいフィールド名を指定。省略した場合はすべてのフィールドに関するエラー情報を取得する
検証後のエラー情報を取得する。返り値は配列として返り、それぞれ次の情報が格納される。
- [0] => FileMaker_Field_Implementation Objectオブジェクト(フィールドに関する詳細情報)が格納される
- [1] => 入力値の制限に抵触した項目が対応する数値として格納
- [2] => 入力値の制限に抵触した入力値が格納
配列1番目はFileMaker_Field_Implementationオブジェクトそのもののため、getName()やdescribeLocalValidationRules()といったFileMaker_Fieldクラスのメソッドをそのまま使用することが可能だ。配列2番目の対応する数値は次のとおり。
- 空欄不可/FILEMAKER_RULE_NOTEMPTY
- タイプ: 数字ではない/FILEMAKER_RULE_NUMERICONLY
- 最大文字数超過/FILEMAKER_RULE_MAXCHARACTERS
- 西暦4桁の日付書式ではない/FILEMAKER_RULE_FOURDIGITYEAR
- タイプ: 時刻ではない/FILEMAKER_RULE_TIMEOFDAY
- タイムスタンプの書式ではない/FILEMAKER_RULE_TIMESTAMP_FIELD
- 日付の書式ではない/FILEMAKER_RULE_DATE_FIELD
- 時刻の書式ではない/FILEMAKER_RULE_TIME_FIELD
配列3番目には実際の入力値が格納される。ひとつのフィールドに複数の入力値の制限を設定している場合は、入力値の制限に抵触する分だけエラー情報が返る。
numErrorsメソッド (Validation.php 60-65行目より)
/**
* Return the number of validation rules that failed.
*
* @return integer Number of failures.
*/
function numErrors()
検証結果中、「入力値の制限」に抵触した数を返す。引数はなし、戻り値はinteger型。
ここまで紹介した2メソッドを使って、実際に試してみよう。ここでのファイル情報、用意したフィールドは次のとおり。
- レイアウト名: fmapi_validate_test_2
- フィールド名: ft_num_notNull, ft_num_typeNum, ft_num_maxLen4, ft_date_typeDate, ft_date_typeTime, ft_timestamp, ft_date, ft_time, ft_num_typeNum_maxLen4
ソースコードは次のとおり。
fmapi_validate_test.php
<?php
include_once('../FileMaker.php');
$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');
$newCommand = $data->newAddCommand('fmapi_validate_test_2');
$newCommand->setField('ft_num_notNull', ''); // 空欄のためエラー
$newCommand->setField('ft_num_typeNum', '1,000'); // 「,」が入っている=数字タイプではないためエラー
$newCommand->setField('ft_num_maxLen4', '39800'); // 最大文字数の「4文字」を超えているためエラー
$newCommand->setField('ft_date_typeDate', '9/16'); // 西暦未入力のためエラー
$newCommand->setField('ft_date_typeTime', '12:60:00'); // 「分」が不正な時刻書式のためエラー
$newCommand->setField('ft_timestamp', '2009/9/16 12:00:00'); // タイムスタンプの書式(MM/DD/YYYY HH:ii:ss)ではないためエラー
$newCommand->setField('ft_date', '2009/9/16'); // 日付の書式(MM/DD/YYYY)ではないためエラー
$newCommand->setField('ft_time', '12:60:00'); // 「分」が不正な時刻書式のためエラー
$newCommand->setField('ft_num_typeNum_maxLen4', '10,000'); // 「,」が入っている=数字タイプではない、「4文字」を超えているためエラー
$validate = $newCommand->validate();
if(FileMaker::isError($validate))
{
// レコード登録前のバリデートエラー処理
echo 'バリデーションエラー数: ' . $validate->numErrors();
// getErrors()で返る配列の2番目に格納されるエラー番号に対応するメッセージ
$errorMessages = array
(
'',
'空欄不可/FILEMAKER_RULE_NOTEMPTY',
'タイプ: 数字ではない/FILEMAKER_RULE_NUMERICONLY',
'最大文字数超過/FILEMAKER_RULE_MAXCHARACTERS',
'西暦4桁の日付書式ではない/FILEMAKER_RULE_FOURDIGITYEAR',
'タイプ: 時刻ではない/FILEMAKER_RULE_TIMEOFDAY',
'タイムスタンプの書式ではない/FILEMAKER_RULE_TIMESTAMP_FIELD',
'日付の書式ではない/FILEMAKER_RULE_DATE_FIELD',
'時刻の書式ではない/FILEMAKER_RULE_TIME_FIELD'
);
?>
<table border="1">
<tr>
<th>フィールド名</th>
<th>エラー内容</th>
<th>入力値</th>
</tr>
<?php
foreach($validate->getErrors() as $error)
{
?>
<tr>
<td><?php echo $error[0]->getName(); ?> </td>
<td><?php echo $error[1] . ' - ' . $errorMessages[$error[1]]; ?> </td>
<td><?php echo $error[2]; ?> </td>
</tr>
<?php
}
?>
</table>
<?php
}
else
{
$result = $newCommand->execute();
if (FileMaker::isError($result))
{
// レコード登録時のエラー処理..
echo 'FileMaker Error Code: ' . $result->getErrorString();
echo '<p>'. $result->getMessage() . '</p>';
}
else
{
// 正常処理..
echo 'done.';
}
}
?>
作成した全フィールドにたいして、入力値の制限に抵触する値をセットし、validateを実行した。結果はテーブルで表示する。これを実際にWebブラウザで表示してみよう。
バリデーションエラーの数と、入力値の制限に抵触したフィールドと内容、入力値がテーブルで表示された。入力値の制限を2つセットした「ft_num_typeNum_maxLen4」は、2つともエラーを捕捉できていることが確認できる |
冒頭でもすこし述べたとおり、フィールドオプションの入力値の制限で設定する「タイプ」と、フィールドの「タイプ」は別扱いされるので注意されたい。単純な登録処理や編集・検索処理と比較すると重ための処理な分、最初に覚えておくべきこともおおいバリデート処理。だが苦労に見合うだけの価値がある機能であることは確かだ。しっかり覚えておこう。