ホーム > アーカイブ > 2007-04
2007-04
CakePHP を簡単に説明する
CakePHP にはモデル、コントローラ、ビューというものがあります。
下記のような URL の場合、
http://www.test.com/tops/index/param1/param2
app/controllers/tops_controller.php コントローラファイル
app/models/top.php モデルファイル
app/views/tops/index.thtml ビューファイル
のような構成になります。
下記のような URL にも対応できます。
http://www.test.com/products/商品ID
この場合は、.htaccess を少し工夫する必要があります。
コントローラ、モデル、ビューのそれぞれの役割/書き方は CakePHPの何か のCakePHPのModelを使う、CakePHPを使う、の PDF ファイルで理解します。
- コメント: 0
- トラックバック(閉): 0
validation の共通化
CakePHP でバリデーションを共通化するにはどうすればいいか?
チェック項目でよく使うバリデーションは app_model.php などに追加すればいい。
今から考えるのはチェックメソッドの共通化ではなく、チェック内容の共通化。
var $validate = array('login_id' => array('rule' => array('alphaNumeric')),'password' => array('rule' => array('alphaNumeric'), 'rule' => array('between', 10, 15),);
例えば上記のようなログイン ID とパスワードをチェックする $validate があるとして、このパターンのバリデーションを複数個所で使いたい時(ログインチェックの時と新規登録の時とか)どのように共通化すればいいか。
普通はモデルのクラス内に直書きしているので関数化しないと共通化できない。ではどのように関数化すれば一番メンテナンスし易くなるかを考える。
- コメント: 0
- トラックバック(閉): 0
モデルの役割と使い方
モデルの役割は大きく分けて 3 つある。
- モデルとデータベースとの関連を定義する
- バリデーション
- 表示処理に必要な独自関数の定義
まず、
1. モデルとデータベースとの関連を定義する
について
CakePHPの何か の「CakePHPのModelを使う」発表資料PDF がわかりやすい
一応順に説明すると
var $name = 'User';
この記述の意味は、モデル名が ‘User’ ということと、このモデルに対応するテーブル名が ‘users’ であることを示す。わざわざ書かなくてもクラス名が User ならデフォルトで ‘User’ 設定される。
var $useTable = 'user_table';
モデルに対応するテーブル名を $name の設定から推測される名前以外を利用したい場合は、この変数で指定する。コントローラから findAll などの関数でアクセスするテーブルはこの変数で指定したものになる。
var $primaryKey = 'user_id';
モデルに対応するテーブルの主キーを設定します。設定しない場合は、主キーはデフォルトで ‘id’ と判断されるので、主キーが ‘id’ 以外の場合は設定してください。
主に上記 3 つの変数を使うことになると思います。
それ以外の関数については 6.3. モデルの変数 を参照してください。$transactional は更新系の処理では必要になると思います。
次に
2.バリデーション
について
「CakePHPのModelを使う」発表資料PDF の P.33-37 と 12章 データバリデーション を読む。
簡単に言うと、$validate 変数に配列を設定し、save() か validates() メソッドを実行すると validation が実行される。
ただ、デフォルトの validation では空チェック、数値チェック、E-MAIL チェックぐらいしかないので、カスタマイズする必要がでてくる。
libs/validators.php への定義値の追加とか PDF の P.33 に書かれているように validates をオーバーライドするとか。
調べると hetimaの日記 – CakePHP 1.1系に1.2系のバリデーションを組み込む がよくまとまってるので同じように組み込んでみる。
app_model.php を app フォルダ直下にコピーし、hetima さんのロジックを組み込む。すると以下のエラーが発生する。
(Model::invalidFields) Parameter usage is deprecated, set the $data property instead
原因は validates() の使い方が 1.2.x から変わっていて、今まで、validates($data) というように引数に $data を渡せていたものが渡せなくなっている。だから以下のようにまず set() してから validates() を呼ぶように書き方を変える。
$data['Top'] = array( 'login_id' => '+*+*+*+*', 'password' => 'abcde', 'name' => '' );$this->Top->set($data);if ($this->Top->validates()) {}
validateErrors() という関数を実行すると同じエラーが発生したのでこちらも変える。
cake/libs/controller/controller.php の validateErrors メソッドを変更する。
function validateErrors() { $objects = func_get_args(); if (!count($objects)) { return false; }
$errors = array(); foreach($objects as $object) { $this->{$object->name}->set($object->data); $errors = array_merge($errors, $this->{$object->name}->invalidFields()); } return $this->validationErrors = (count($errors) ? $errors : false); }
validation の詳しい使い方は CakePHP のおいしい食べ方: CakePHP View を参照する。よく読まないと理解できないが、しっかり読めばなんとなくわかってくる。
1.2.x の validation の種類は cakebaker » Validation with CakePHP 1.2 を参照。(下記のような感じになる)
var $validate = array('username' => array('rule' => array('alphaNumeric')));
blank を試してみるとなぜかうまく動かない。
#2157 (Validate::blank return incorrect boolean) というチケットを見つけたのでバグかと思うとそんなこともないらしい。
よく cakebaker » Validation with CakePHP 1.2 を読むと ‘blank’ は空(から)という意味ではないよう。必須チェックは 1.1.x と同じ、VALID_NOT_EMPT でチェックすること。
最後に
3.表示処理に必要な独自関数の定義
について
PHP/CakePHP/CakePHPのモデルをエンティティとして扱う – Happy Engineer Life でやってる税込価格を表示する方法を考える必要がある。まったく真似するのもあり。
CakeShop/イテレーション/2-A2 商品を注文する – Happy Engineer Life のメッセージの共通化もやっておきたい。
- コメント: 0
- トラックバック(閉): 0
cake で共通化
- 2007/04/07
- その他
基本はコンポーネントで共通化できるよう。ただデータベースアクセスが必要な場合は、 “requestAction” を使って共通化するとよさそう。
以下つづく。。。
- コメント: 0
- トラックバック(閉): 0
Meadow での .emacs の設定
- 2007/04/06
- その他
以下は私の最新の .emacs の設定です。変更する度に更新していこうと思います。
(cd “~”)
(set-language-environment “Japanese”)
(mw32-ime-initialize)
(setq default-input-method “MW32-IME”)
;;euc
(setq default-buffer-file-coding-system ‘euc-japan-unix)
;;font
(create-fontset-from-request “private-fontset”
‘((width . 8)
(height . 16)
(fixed . t)
(italic . nil))
‘((family . “MS ゴシック”)
(family . “Courier New”)))
;; font shinonome(不要なら nil にする)
(setq bdf-font-directory-shinonome “D:/apps/Meadow/fonts/shinonome”)
(setq bdf-use-shinonome12 t
bdf-use-shinonome12min t
bdf-use-shinonome12maru t
bdf-use-shinonome14 t
bdf-use-shinonome14min t
bdf-use-shinonome16 t
bdf-use-shinonome16min t)
(load “meadow2-shinonome-fontset”)
;;font default set
(setq default-frame-alist
(append (list ‘(font . “shinonome12″)
‘(top . 10)
‘(left . 20)
‘(width . 80)
‘(height . 50)
)
default-frame-alist))
;;color
(global-font-lock-mode t)
(require ‘font-lock)
;;transient-mark-mode
(transient-mark-mode t)
;;line number
(require ‘setnu)
(global-set-key [f12] ‘setnu-mode)
;;toggle
(global-set-key [f8] ‘toggle-truncate-lines)
;;windmove-default-keybindings
(windmove-default-keybindings)
;;not use backupfile
(setq make-backup-files nil)
;;iswitchb-mode
(iswitchb-mode t)
;;shell
(setq explicit-shell-file-name “bash.exe”)
(setq shell-file-name “bash.exe”)
(setq shell-command-switch “-c”)
;;tab
(setq-default tab-width 4)
(setq-default c-basic-offset 4)
(setq-default indent-tabs-mode nil)
;;php
(load-library “php-mode-120″)
(require ‘php-mode)
(add-to-list ‘auto-mode-alist ‘(“\\.inc$” . php-mode))
(add-to-list ‘auto-mode-alist ‘(“\\.tpl$” . php-mode))
(add-to-list ‘auto-mode-alist ‘(“\\.thtml$” . php-mode))
(add-hook ‘php-mode-user-hook
‘(lambda ()
(setq tab-width 4)
(setq c-basic-offset 4)
(setq indent-tabs-mode nil)
(setq php-manual-path “~/php/doc”))
)
;;show-paren-mode
(show-paren-mode t)
(setq show-paren-style ‘mixed)
(set-face-background ‘show-paren-match-face “gray10″)
(set-face-foreground ‘show-paren-match-face “SkyBlue”)
;;svn todo
(add-to-list ‘vc-handled-backends ‘SVN)
;;zengaku space tab
(defface my-face-b-1 ‘((t (:background “medium aquamarine”))) nil)
(defface my-face-b-2 ‘((t (:background “gray26″))) nil)
(defface my-face-u-1 ‘((t (:foreground “SteelBlue” :underline t))) nil)
(defvar my-face-b-1 ‘my-face-b-1)
(defvar my-face-b-2 ‘my-face-b-2)
(defvar my-face-u-1 ‘my-face-u-1)
(defadvice font-lock-mode (before my-font-lock-mode ())
(font-lock-add-keywords
major-mode
‘(
(“ ” 0 my-face-b-1 append)
(“\t” 0 my-face-b-2 append)
(“[ ]+$” 0 my-face-u-1 append)
)))
(ad-enable-advice ‘font-lock-mode ‘before ‘my-font-lock-mode)
(ad-activate ‘font-lock-mode)
(add-hook ‘find-file-hooks ‘(lambda ()
(if font-lock-mode
nil
(font-lock-mode t))) t)
- コメント: 0
- トラックバック(閉): 0
log4php で Segmentation fault
- 2007/04/05
- その他
log4php をサーバーにセットアップすると以下のようなエラーが発生しました。
[notice] child pid 10388 exit signal Segmentation fault (11)
めっちゃ悩んだ結果、答えは、log4php のソースコードのヘッダーコメントに日本語の文字コードで解釈できない文字があり、そこでひっかかっていたようです。
全てのソースを euc lf に変換することで Segmentation fault エラーは発生しなくなりました。
vtiger Open Source CRM Discussions を見て log4php のバグだと勘違いして調べていた自分がばからしい。
あとは PHP/CakePHP/CakePHPのログをLog4phpに切り替える – Happy Engineer Life を参考に log4php のバグを直すだけ。
log4php\LoggerPropertyConfigurator.phpの509行目 の正しい修正は &parseCategory → parseCategory となる。
log4php.properties の設定は以下のとおり
log4php.rootLogger=DEBUG, Rlog4php.appender.R=LoggerAppenderRollingFilelog4php.appender.R.file=/..絶対パスで../app/tmp/logs/error_log.txtlog4php.appender.R.layout=LoggerPatternLayoutlog4php.appender.R.layout.ConversionPattern=%d [%t] %-5p %c - %m%nlog4php.appender.R.MaxFileSize=10240log4php.appender.R.MaxBackupIndex=3
- コメント: 0
- トラックバック(閉): 0
cake の webroot と DocumentRoot が違う場合
- 2007/04/04
- その他
/cake_install/app/webroot と www サーバの DocumentRoot が違う場合、CakePHP が自動で生成するリンクのパスが合わない。
例えば
/cake_install/app/webroot=/var/www/html/cake
DocumentRoot=/var/www/html/
の場合とか。
こういう場合は以下を参照。
Webプログラミングに関するメモ: CakePHPでmod_rewriteを使わない場合の設定
でうまくいったと思ったら、URI の中に index.php が含まれてしまい見た目が悪いためこの方法は使えない。。。
- コメント: 0
- トラックバック(閉): 0
Oracle 9i with CakePHP
CakePHP で Oracle を使ってアクセスすると以下のようなエラーが発生して困った。
Fatal error: Call to a member function on a non-object in
/...../cake/cake/libs/model/dbo/dbo_adodb.php on line 298
Oracle 9i with CakePHP でも同じ問題で躓いている人がいたが、解決の手がかりはなし。
CakePHP で
CaekPHP の本家を見ていると、
#1526 (Oracle+ADODB+CakePHP Call to a member function MetaType() on a non-object in dbo_adodb.php) – CakePHP : The Rapid Development Framework for PHP – Trac
・resolution set to wontfix.
We are creating a native Oracle driver that will be used instead of Adodb, there are too many changes that are specific to Oracle for us to change the Adodb dbo.
This should be completed shortly and can be placed in your own app/models/dbo
というように、CakePHP としては対応しません、ということになっている。(wontfix)
仕方がないので、いろいろ探していると、バージョン 1.2.x の方に dbo_oracle.php というものがあったので試してみるもやっぱりエラー。
Parse error: parse error, unexpected '&', expecting T_VARIABLE or '$' in
/...../cake/cake/libs/model/dbo/dbo_oracle.php on line 217
もう少し探すと
#2024 (dbo_oracle: Oracle preserved keys and fullTableName) – CakePHP : The Rapid Development Framework for PHP – Trac
にもバグ修正後の dbo_oracle.php があったので使ってみるとエラーはなくなりました。
ただ開発中のソースなのでこのまま問題なく使用できる保障はない。
2007/04/17 追記
オラクルでトランザクションを使いたいので、以下から最新の dbo_oracle.php を取得し置き換えました。
root/branches/1.2.x.x/cake/libs/model/datasources/dbo/dbo_oracle.php
Revision 4620
このままだとエラーになるので、何点か修正。
31 行目ぐらいに
uses('model'.DS.'datasources'.DS.'dbo_source');
を追加。
150、151 行目の execute 文をコメント化
//$this->execute('ALTER SESSION SET NLS_SORT=BINARY_CI');
//$this->execute('ALTER SESSION SET NLS_COMP=ANSI');
217 行目の “&” がエラーになるので削除。※ “&” の意味を調べる必要あり
foreach ($fields as $value) {
これぐらい修正するととりあえず動きます。
トランザクションのテストはまだしてません。
テストしてみてまだエラーだったので、
1.1.x.xの場合 Re: トランザクションを実現するには
にあるように、以下 2 ファイルを修正する
cake/libs/model/datasources/dbo_source.php
cake/libs/model/model_php4.php(サンプルはmodel_php5.php となっているが同じコードを php4 に使っても大丈夫)
ここまでやると、エラーは発生しなくなりました。
あとは複数テーブルのコミット、ロールバックの確認。
2007/04/20 追記
複数テーブルのコミット、ロールバックも OK でした。
- コメント: 0
- トラックバック(閉): 0
ホーム > アーカイブ > 2007-04