Home > CakePHP | PHP > CakePHP テーブルのカラムサイズでvalidate

CakePHP テーブルのカラムサイズでvalidate

  • 2007-06-27 (水) 23:48
  • CakePHP | PHP
  • このエントリーをはてなブックマークに追加
この記事の所要時間: 241

モデルで文字列の長さをvalidateする際にテーブルのカラムサイズを使う方法です。

CakePHPではモデルがテーブルのカラム情報を保持しているのですが、この情報にはカラム名やデータ型の他にカラムサイズ(varchar(N)等)も含まれています。

そこでモデルのvalidateでこの値を使えば最低限テーブルのカラムに収まるかどうかはチェックできます。

ここでは以下のようなテーブルでnameとemailの文字列長をチェックします。(DBはPostgreSQL)

SQL:
  1. CREATE TABLE users (
  2. id        serial            PRIMARY KEY
  3. ,name   varchar(50)   NOT NULL
  4. ,email   varchar(100)   NOT NULL
  5. );

1. AppModelにカラムサイズ取得、文字列長チェックメソッドを追加する

AppModelにカラムサイズ取得用メソッド(getColumnLength)と文字列長チェックメソッド(validatesLength)を記述します。

PHP:
  1. <?php
  2. class AppModel extends Model {
  3.   /**
  4.    * Returns the column type of a column length in the model
  5.    *
  6.    * @param string $column The name of the model column
  7.    * @return integer
  8.    * @access public
  9.    */
  10.   function getColumnLength($column) {
  11.     $columns = $this->loadInfo();
  12.     $columns = $columns->value;
  13.     $cols = array();
  14.  
  15.     foreach($columns as $col) {
  16.       if ($col['name'] == $column) {
  17.         return $col['length'];
  18.       }
  19.     }
  20.     return null;
  21.   }
  22.  
  23.   /**
  24.    * valid value length
  25.    *
  26.    * @param array $data
  27.    * @param string $fields
  28.    * @access public
  29.    */
  30.   function validatesLength($data, $fields) {
  31.     foreach ($fields as $v) {
  32.       $len = $this->getColumnLength($v);
  33.       if (!empty($data[$v]) && mb_strlen($data[$v])> $len) {
  34.         $this->invalidate($v . '_len_' . $len);
  35.       }
  36.     }
  37.   }
  38. }
  39. ?>

2. モデルで文字列長をチェックする

モデルで文字列長チェックを呼びます。単に$dataとvalidatesLengthメソッドにチェックするカラムを配列で渡すだけでokです。

validatesLength内部ではテーブルのカラムサイズで文字列長チェックを行い、エラーならinvalidateメソッドを呼びます。このinvalidateメソッドに与える値[カラム名 + '_len_' + カラムサイズ]がポイントです。これをモデルの$validationErrorsに持たせておくことにより、ビューで正規の文字列長を含んだエラーメッセージを動的に出力することができます。

PHP:
  1. <?php
  2.   function validates($data = array()) {
  3.     if (!parent::validates($data)) {
  4.       return false;
  5.     }
  6.     if (empty($data)) {
  7.       $data = $this->data;
  8.     }
  9.     $data = $data['User'];
  10.  
  11.     // 文字列長チェック
  12.     $list = array('name', 'email');
  13.     $this->validatesLength($data, $list);
  14.   }
  15. ?>

3. HtmlExtヘルパでエラーメッセージを出力

文字列長エラーメッセージを動的に出力するメソッド(tagLengthErrorMsg)をHtmlヘルパーを継承したHtmlExtに定義しておきます。

PHP:
  1. <?php
  2. class HtmlExtHelper extends HtmlHelper {
  3.   /**                       
  4.    * lengthエラーメッセージ表示
  5.    *                   
  6.    * @param string $field
  7.    * @param string $name
  8.    * @return string
  9.    */                         
  10.   function tagLengthErrorMsg($field, $name) {
  11.     if (empty($this->validationErrors)) {
  12.       return null;
  13.     }
  14.                              
  15.     $this->setFormTag($field);
  16.     foreach ($this->validationErrors[$this->model] as $k => $v) {
  17.       if (preg_match("/^" . $this->field . "_len_([0-9]+)$/", $k, $m)) {
  18.         $message = sprintf("%sは%d文字以内で入力してください。", $name, $m[1]);
  19.         return $this->tagErrorMsg($field . "_len_" . $m[1], $message);
  20.       }
  21.     }
  22.     return null;
  23.   }
  24. }
  25. ?>

4. ビューテンプレートでヘルパ呼び出し

最後にビューテンプレートで先程のtagLengthErrorMsgメソッドを呼び出します。これは引数としてカラム名とエラーメッセージ用項目名を与えます。

PHP:
  1. <!-- エラー時は「氏名は50文字以内で入力して下さい。」を表示 -->
  2. <?php echo $htmlExt->tagLengthErrorMsg('User/name', '氏名'); ?>
  3. <!-- エラー時は「メールアドレスは100文字以内で入力して下さい。」を表示 -->
  4. <?php echo $htmlExt->tagLengthErrorMsg('User/email', 'メールアドレス'); ?>

ソース内に文字列長を書かなくて良い

この方法では文字列長をテーブル定義から取得するので、ソースに文字列長を書く必要がありません。もしテーブルのカラムサイズが変わってもソースはそのままで新しいカラムサイズに対応することができます。

(ちなみにtext型などカラムサイズが無いものについてはテーブル定義情報(モデルの$_tableInfo)に直接文字列長を入れるという方法もあります。)

ここでは1.1系で記述していますが、1.2系ではvalidateが柔軟な形になっているので2.のモデルでのチェックはもうちょっとスマートに書けそうです。

トラックバック:0

このエントリーのトラックバックURL
http://www.1x1.jp/blog/2007/06/cakephp_validate_length.html/trackback
Listed below are links to weblogs that reference
CakePHP テーブルのカラムサイズでvalidate from Shin x blog

Home > CakePHP | PHP > CakePHP テーブルのカラムサイズでvalidate

検索
フィード
メタ情報

Return to page top