リクエストパラメータの検証

guessworkでは、「ヴァリデータクラス」を作成することでリクエストパラメータの検証およびエラーメッセージの設定を行うことができます。

ヴァリデータクラスはコントローラクラスと1対1で対応するクラスで、各アクションメソッドに対応するヴァリデーションメソッドを持ちます。通常はValidatorクラスを継承して定義します。

ヴァリデータクラスの定義

ヴァリデータクラス名に命名規則はありませんが、クラス名を「コントローラクラス名のControllerをValidatorに置き換えた」ものにしておくと、guessworkがコントローラ名からヴァリデータクラスを推測して自動的に関連付けてくれるようになります。

以下は、検索キーワードが入力されているかをチェックするヴァリデータとそれを利用するコントローラのサンプルです。

検索コントローラ用ヴァリデータ

class SearchValidator extends Validator
{
    // $valuesはコントローラのクラス変数名をキーとする配列
    function validateSearch($values)
    {
        if ($this->isEmpty($values["keyword"])) {
            // 検証エラーが発生した場合はエラーメッセージを設定
            $this->addError("keyword", "キーワードが入力されていません");
        }
    }
}
?>

検索コントローラ

require_once "SearchValidator.class.php";

class SearchController extends Controller
{
    var $_gw_default_action = "input";
    var $_gw_template_class = "/path/to/Smarty.class.php";
    var $_gw_template_templates_dir = "/path/to/templates";
    var $_gw_template_compile_dir = "/path/to/templates_c";

    // エラーメッセージ配列
    var $errors;

    // 検索キーワード
    var $keyword;

    // 初期化
    function init()
    {
        $this->errors = array();
        $this->keyword = "";
    }

    // 検索フォーム表示
    function executeInput()
    {
        // $this->validate()を呼び出さなければ検証は行われない
    }

    // 検索
    function executeSearch()
    {
        // 検証のためにヴァリデータクラスのvalidateSearch()が呼び出される
        if (!$this->validate()) {
            // エラーがあった場合はエラーメッセージを取得
            $this->errors = $this->getErrors();
            // 入力フォームテンプレートを表示して終了
            return $this->render("search/input");
        }

        // 検証成功時の処理をここに記述
    }
}

executeSearch()メソッド内のvalidate()メソッド呼び出しによって、ヴァリデータクラスのvalidateSearch()メソッドが呼び出されています。検証用メソッド名はアクションメソッド名から推測されます。

ヴァリデータクラスのvalidateSearch()メソッドでは、引数$valuesの要素を検証してエラーメッセージを設定しています。$valuesにはコントローラクラスのクラス変数のうち、リクエストパラメータが自動設定される変数の変数名および値が以下のような構造で格納されています。

array("keyword" => "")

検証に使用されているisEmpty()メソッドは引数が空文字列の場合にtrueを返すもので、Validatorクラスで定義されています。

if ($this->isEmpty($values["keyword"])) {

エラーメッセージはaddError()メソッドで設定します。1つ目の引数にはエラーメッセージの識別名を、2つ目の引数にはエラーメッセージを指定します。このメソッドもValidatorクラスで定義されています。

$this->addError("keyword", "キーワードが入力されていません");

エラーメッセージはControllerクラスのgetErrors()メソッドによって取得することができます。戻り値はエラーメッセージの識別名をキーとする配列になっており、テンプレートに引き渡すことで以下のように参照することができます。

{if $errors}
  <p class="error">エラーが発生しました</p>
{/if}

名前: <input type="text" name="name" size="20" /><br />
{if $errors.name}<span class="validationError">{$errors.name}</span><br/>{/if}

任意の名前のヴァリデータクラスを利用する

ヴァリデータクラス名として「コントローラクラス名から推測できない名前」を使用する場合は、以下のようにしてコントローラクラスが使用するヴァリデータクラス名を設定する必要があります。

class SearchController extends Controller
{
    var $_gw_validator_class = "FooValidator";

なぜコントローラ毎にヴァリデータを持つのか

guesswork以外の多くのフレームワークではJava用PHP用を問わず、「空文字列かどうか」、「半角n文字以上かどうか」、「半角数字かどうか」といった条件をフォーム入力項目名とペアで設定ファイルに記述していくようなスタイルが大半です。このスタイルはいちいちヴァリデータクラスを作成する必要がなく、検証ルールを一元的に管理できるためとても理想的ですが、検証すべき条件が複雑になってくると既存の枠組みではなかなかカバーしきれなくなってきます。

結果としてフレームワークの枠組みによる検証とPHPコードによる検証が混在してしまい、またPHPプログラマに「検証用設定ファイル」のような(独自で使い回しのきかない)知識を要求することにもなるため、guessworkでは「コーディングレスな検証」を避けています。