Categories: php

Yiiでvalidatorを作成する。

Yiiのモデルで入力値をバリデートする際、バリデータの設定方法としては、

  • モデル内に関数として記述する。
  • バリデータ用のファイルを作成する。

という2つの方法があります。

モデル内に関数として記述する。

モデル内に以下のような記述をすれば、addressフィールドのバリデートには、address_check関数を利用するようになります。

<?php
class Hoge extends CFormModel
{
  public $address;

  public  rules()
  {
    return array(
      array('address', 'address_check'),
    );
  }

  public  address_check($attribute,$params)
  {
    if(!preg_match('/^.+(都|道|府|県).+(市|区|町|村).+$/', $this->address))
      $this->addError('address','住所が違います。');
  }
}

バリデータに引数を渡したい場合は、

array('address', 'address_check'),

array('address', 'address_check', 'param1'=>'value1', 'param2'=>'value2'),

のようにしたら、address_check($attribute,$params)の$attributeには「address」が$paramsには、

array(
  'param1'=>'value1',
  'param2'=>'value2',
)

が設定されます。

バリデータ用のファイルを作成する。

protected/extensions/MyValidators/addess.phpというファイルを以下のように作成します。

<?php
class address extends CValidator
{
  private $address_pattern = '/^.+(都|道|府|県).+(市|区|町|村).+$/';

  /**
   * Validates the attribute of the object.
   * If there is any error, the error message is added to the object.
   * @param CModel $object the object being validated
   * @param string $attribute the attribute being validated
   */  protected  validateAttribute($object,$attribute)
  {
    // extract the attribute value from it's model object
    $value=$object->$attribute;
    if(!preg_match($this->address_pattern, $value))
    {
      $message=$this->message!==null?$this->message:Yii::t('yii','{attribute} が正しくありません。');
      $this->addError($object,$attribute,$message);
    }
  }

  /**
   * Returns the JavaScript needed for performing client-side validation.
   * @param CModel $object the data object being validated
   * @param string $attribute the name of the attribute to be validated.
   * @return string the client-side validation script.
   * @see CActiveForm::enableClientValidation
   */  public  clientValidateAttribute($object,$attribute)
  {
    $message=$this->message;
    if($message===null)
      $message=Yii::t('yii','{attribute} が正しくありません。');
    $message=strtr($message, array(
        '{attribute}'=>$object->getAttributeLabel($attribute),
    ));

      // check  parameter used in the validation rule of our model
      $condition="!value.match({$this->address_pattern})";

      return "
  if(".$condition.") {
      messages.push(".CJSON::encode($message).");
  }
  ";
  }
}

上記のvalidateAttribute関数がphp内のバリデータで利用されるもの、clientValidateAttribute関数がクライアントサイドのJavascriptのバリデータで利用されるものとなります。
なお、両関数の引数の$objectはバリデートされるモデル(この場合はHoge)、$attributeはバリデートされるフィールド名(この場合はaddress)が入っています。

モデルでは、

array('address', 'ext.MyValidators.address'),

のように書けばprotected/extensions/MyValidators/addess.phpをバリデータとして利用するようになります。

なお、

array('address', 'ext.MyValidators.address', 'param1'=>'value1', 'param2'=>'value2'),

のようにバリデータに引数を渡したい場合は、protected/extensions/MyValidators/addess.phpを

<?php
class address extends CValidator
{
  public $param1='';
  public $param2='';

のように変更すれば、validateAttribute関数やclientValidateAttribute関数から利用できるようになります。

 

用途に応じてですが、ファイルを作成したほうが、クライアントサイドのバリデータも書ける、他でも使いまわせるという点からメリットがあると思います。

 

nakade

Share
Published by
nakade
Tags: Yii