Posts tagged CakePHP
PHP 開発に使う10個のツール
2DaveDevelopment ? Archive ? 10 tools for Modern PHP Development で「PHP の開発に使われている10個のツール」が紹介されていました。 (続きを読む…)
CakePHP1.2 バリデーションで共通ルールを作成するときに便利な userDefined
0CakePHP1.2 バリデーションのルールを調べているときに気になっていた Validation クラスにある userDefined に関して調べてみました。
cake/libs/validation.php
function userDefined($check, $object, $method, $args = null) { return call_user_func_array(array(&$object, $method), array($check, $args)); }
と定義されています。
call_user_func_array は PHP の関数で、関数やクラスのメソッドをコールすることができます。
つまり独自バリデーションがこれを使用して実装できるということです。
使用方法はモデルに以下のようにバリデーションを定義します。
var $validate = array( 'field' => array('rule' => array('userDefined', 'Model', 'method_name')), ); function method_name ($data) { /* バリデーションのチェック エラーなら false 、エラーなしなら true を返す */ }
ただこれだと下記のように書けるのであまりありがたみがない。
var $validate = array( 'field' => array('rule' => array('method_name'), );
何に使えばいいのかと考えたところ、クラス名、メソッド名が指定できるのでシステムで共通のバリデーションを設定するときに使えるのではと思いました。多分これが一番うれしいところではないかと思います。
※ただ、app_model.php に共通にしたいバリデーションチェック用のメソッド名を書けばそれでいけるような気もする。
CakePHP1.2 バリデーションのルール
2CakePHP1.2 のバリデーションのメモです。
詳しくは cake/libs/validation.php を見ると分かりやすいです。
半角英数字のみ
alphaNumeric
var $validate = array('field' => array('rule' => array('alphaNumeric')));
文字列の長さ
between
var $validate = array('field' => array('rule' => array('between', 6, 8)));
半角で6文字以上8文字以内
文字列が空
blank
var $validate = array('field' => array('rule' => array('blank')));
クレジットカード番号
cc
var $validate = array('field' => array('rule' => array('cc')));
比較
comparison
var $validate = array('field' => array('rule' => array('comparison', '>', 10)));
‘==’, ‘!=’, ‘< =’, など使用できる
正規表現
custom
var $validate = array('field' => array('rule' => array('custom', '/^[0-9]{3}\-[0-9]{4}$/')));
例として NNN-NNNN 形式の郵便番号のバリデーション
日付
date
var $validate = array('field' => array('rule' => array('date', 'ymd')));
‘dmy’, ‘mdy’, ‘ymd’, ‘dMy’, ‘Mdy’, ‘My’, ‘my’ が使用可
小数点の桁数チェック
decimal
var $validate = array('field' => array('rule' => array('decimal', 2)));
var $validate = array('field' => array('rule' => array('decimal', null, '/^[0-9]{2}\.[0-9]{2}$/')));
正規表現を指定してチェックすることも可。
メールアドレス
var $validate = array('field' => array('rule' => array('email')));
=== での比較
equalTo
var $validate = array('field' => array('rule' => array('equalTo', 'hoge')));
型も含めて等しいかチェック
拡張子
extension
var $validate = array('field' => array('rule' => array('extension', array('gif', 'jpg')));
ファイルの拡張子をチェック。許可したい拡張子を配列で指定。デフォルトは array(‘gif’, ‘jpeg’, ‘png’, ‘jpg’)
IPアドレス
ip
var $validate = array('field' => array('rule' => array('ip')));
最小文字数
minLength
var $validate = array('field' => array('rule' => array('minLength', 6)));
最大文字数
maxLength
var $validate = array('field' => array('rule' => array('maxLength', 12)));
数字
numeric
var $validate = array('field' => array('rule' => array('numeric')));
数字の範囲チェック
range
var $validate = array('field' => array('rule' => array('range', 0, 100)));
注意点は指定した数字は含まれない
上の例では 1?99 までが true
var $validate = array('field' => array('rule' => array('range')));
とすると有限数かどうかのチェック
URL
url
var $validate = array('field' => array('rule' => array('url')));
CakePHP1.2 モデルの generateList は非推奨メソッドなので find(’list’) を使用する
3CakePHP で select タグを作成する際に CakePHP1.1 ではモデルの generateList メソッドを使用しましたが、このメソッドは CakePHP1.2 では非推奨メソッドになっているようです。その代わりに find メソッドを使用します。
$this->Model->generateList();
と書く代わりに
$this->Model->find('list');
と書きます。
find メソッドのこの書き方は他に
- find(‘count’)
- レコード数を取得する。COUNT(*) の SQL を実行する
- find(‘first’)
- 最初のレコードを取得する。 LIMIT 1 で SQL を実行する
- find(‘all’)
- 全てのレコードを取得する。findAll と同等。
findAll は内部で find(‘all’) を実行している。
などがあります。
CakePHP1.2 Form ヘルパーで日付のフォームを作る
1CakePHP1.2 の Form ヘルパーを使用して日付のフォームを作成したときのメモです。
$attr = array('minYear' => 2000, 'maxYear' => date('Y'), 'separator' => ' / '); echo $form->dateTime('Model/field', 'YMD', 'NONE', date('Y-m-d'), $attr);
とすると下のような日付を選択するフォームができます。
第2引数の ‘YMD’ で年月日の並び順を指定します。日付を表示しない場合は ‘NONE’ を指定します。
- NONE
- 非表示
- YMD
- 年月日の順に表示
- DMY
- 日月年の順に表示
- MDY
- 月日年の順に表示
第3引数で時間表示の指定をします。
- NONE
- 非表示
- 12
- 時間を12時間表示
- 24
- 時間を24時間表示
第4引数でデフォルトの日時を指定します。
第5引数で属性を指定します。
- separator
- 日付の select タグの間に表示する文字
- minYear
- 開始する年
- maxYear
- 終了する年
- interval
- 分を何分刻みで表示するか
CakePHP1.2 文字コードを EUC-JP に設定する
1現在開発しているシステムが文字コードを EUC-JP で制作しなければいけないのですが、今まで CakePHP は UTF-8 でしか制作したことがなく、設定方法などメモしておきます。開発に使用しているのは CakePHP1.2 です。
データベースの文字コード
app/config/database.php
var $default = array( 'driver' => 'mysql', 'persistent' => false, 'host' => 'localhost', 'port' => '', 'login' => 'user', 'password' => 'password', 'database' => 'database_name', 'schema' => '', 'prefix' => '', 'encoding' => 'ujis' );
EUC のときは encoding に ujis と設定します。
ちなみに
Shift-JIS のときは sjis
UTF-8 のときは utf8
とします。
これは MySQL の SET NAMES でそのまま使用されるためです。
システムの文字コード
CakePHP1.2 では下記のように設定します。
app/config/core.php
Configure::write('App.encoding', 'euc-jp');
CakePHP 1.1 の方法はちょっとコードを調べたのですが、 core.php などにも特に設定するところがなく分かりませんでした。分かる方いらっしゃったら教えてください。
CakePHP PHP4 のとき findByカラム名の注意点
1現在開発しているシステムで初めて PHP4 で CakePHP を使用しています。
PHP4 で CakePHP を使用するときの注意点です。
ユーザID で検索するときに findBy カラム名をよく使います。
$this->Model->findByUserId($user_id);
これを PHP4 で使用するときは
$this->Model->findByUser_Id($user_id);
とアンダーバーを入れる必要があります。
CakePHP1.2 のバリデーション
12CakePHP 1.2 を使用してフォームを作成してバリデーションを使用したメモです。
下記サイトを参考にさせていただきました。
cakePHP 1.2のバリデーションを理解する – cakephp – クロアチアで働くプログラマー日記
例としてメールアドレスを2回入力させるフォームを考えて見ます。
バリデーションルールとして
- 必須項目
- メールアドレスとして正しい
- メールアドレスがユニーク
- 2回入力したメールアドレスが一致する
モデルにバリデーションを定義する
var $validate = array( 'email' => array( 'unique' => array( 'rule' => array('checkUnique', 'email'), 'message' => 'メールアドレスは既に登録されています' ), 'rule1' => array( 'rule' => array('email'), 'message'=>'メールアドレスが正しくありません' ), 'required' => array( 'rule'=>VALID_NOT_EMPTY , 'message' => '必須項目です' ), ), 'email_confirm' => array( 'rule1' => array( 'rule'=> array('checkCompare'), 'message'=>'一致しません' ), ), );
私はエラーメッセージをバリデーション定義にまとめておきたいので、上記のように各ルールに
'message' => 'エラーメッセージ'
として定義しています。
ここで定義しておけば、後でビューに書くフォームヘルパーでフォームを出力するときに引っかかったエラーを自動的に出力することができます。
また、自分でバリデーション関数を作成してチェックすることもできます。それが checkUnique と checkCompare です。
メールのユニークチェックは参考サイトを参考にさせていただきました。
function checkUnique($field){ foreach( $field as $key => $value ){ $this->recursive = -1; $found = $this->find(array("{$this->name}.$key" => $value)); return !$found; } }
次にメールアドレスを2回入れたものが一致するかのチェックです。
これはパスワードなどでもたまに使用するので汎用性を持たせてあります。
例えばメールアドレスのフィールド名が email の場合、確認用のフィールド名は ‘_confirm’を付けて email_confirm としておけばこの2つが一致するかチェックします。
function checkCompare($field) { foreach( $field as $key => $value ){ if (preg_match('/^(.+)_confirm$/', $key, $regs)) { return $this->data[$this->name][$regs[1]] == $this->data[$this->name][$key]; } } }
ビューでフォームを設定
<?php echo $form->input('User/email', array('type'=>'text')); ?> <?php echo $form->input('User/email_confirm', array('type'=>'text')); ?>
このように書いておけばバリデーションエラーがある場合は、モデルのバリデーションに定義したエラーメッセージを自動的に出力してくれます。
ちなみに上記のように書くと input タグの前に email などのフィールド名が出力されます。これを消したい場合は
<?php echo $form->input('User/email', array('type'=>'text', 'label'=>'')); ?>
と書くと表示されなくなります。
追記:
コメントで教えていただきました。label=>” だと表示されないが、label タグは残るので
<?php echo $form->input('User/email', array('type'=>'text', 'label'=>false)); ?>
とするとラベルタグも出力されなくなります。
コントローラでバリデーションチェック
以下のようになります。
function action() { if ($this->data) { if ($this->User->create($this->data) && $this->User->validates()) { // バリデーションOK } } }
他にもいろいろフォーム気がついた点があったのでそれはまた後でまとめます。
CakePHP Ajax のフォームを作成する
5今さらなのですが CakePHP1.1 で Ajax のフォームを作成するというのをやったのでメモしておきます。
Ajax , Javascript ヘルパーを使用できるようにする
コントローラで Ajax, Javascritp ヘルパーを使用できるようにする。
var $helpers = array('Ajax', 'Javascript');
prototype.js を読み込む
webroot/js に prototype.js を配置し、ビューで読み込みます。
<?php echo $javascript->link('prototype'); ?>
ビューでフォームを作成する
今回は submit ボタンを押した後、更新中には submit ボタンを消して変わりに「更新中」というメッセージを表示し、更新終了後にメッセージをボタンの下の id=ajax_message に表示するようにしました。
<?php $options = array( "update" => "ajax_message", "loading" => "Element.hide('ajax_button'); Element.show('ajax_loading');", "complete" => "Element.show('ajax_button'); Element.hide('ajax_loading');", ); echo $ajax->form("/controller/action/", "post", $options); ?> <?php echo $html->input('Model/Field', array('type'=>'text')); ?><br> <input type="submit" id="ajax_button"> <div id="ajax_loading" style="display:none;">更新中...</div> <div id="ajax_message"></div>
$ajax->form の $options の
“update” で更新するメッセージ領域を指定し、
“loading”でアップロード中の動き、
“complete” で処理終了後の動き
を指定しています。
コントローラに Ajax で処理するアクションを作成
function action() { $this->layout = 'ajax'; /* $this->data にフォームの内容が渡るので必要な処理を書く */ $this->Model->id = $this->data['Model']['id']; $this->Model->saveField("Field", $this->data['Model']['Field'], true); }
$this->layout で ‘ajax’ を指定して余計なヘッダ、フッタが出ないようにします。
Ajax で出力するビューを作成する
上のコントローラのアクションで出力するビューを作成します。
上の例では saveField でフォームから送られてきたデータを使用して更新処理しています。その結果によってメッセージを送信します。
<?php if($msg=$error->messageFor('Model/Field')) { echo $msg; } else { echo "更新しました"; } ?>
CakePHP1.2 バッチ処理
2CakePHP1.2 にシェル機能というのがあるのを知りました。下記エントリでメールからの処理を実際に行う方法が紹介されています。
メール受信からのシェル機能実行 – Writing Some Code
ちょうど CakePHP1.2で開発中のシステムで cron でのバッチ処理があるのでそれに応用してみたときのメモです。
バッチ処理で実行させるシェル機能を作成
今回は test という名前のシェル名にします。
app/vendors/shells/test.php を作成します。
< ?php class TestShell extends Shell { var $uses = array('Model'); function actionName(){ /* 実際の処理を書きます */ /* $this->uses に追加したモデルが使用できます */ $lists = $this->Model->findAll(); } } ?>
シェルスクリプト
下記のようなシェルスクリプトを作成して cron から実行させます。
#!/bin/sh cd /path/to/app ../cake/console/cake test actionName
シェルスクリプトなしで直接 cake を実行する方法もある
cake を実行するときにカレントディレクトリが app でないとだめなのですが、
-app /path/to/app
のように -app オプションで実行時に app のパスを指定することもできます。
その場合は下記のようになります。
/path/to/cake/console/cake test actionName -app /path/to/app
これを直接 cron から実行させればシェルスクリプトなしでも実行できます。
その他
vendors/shells 内のファイルですが、ファイル名が hoge_foo.php だった場合、クラス名は HogeFooShell ですが、実行するときは
cake/console/cake hoge_foo actionName
となるようです。