CakePHPの履歴
マニュアル
http://book.cakephp.org/
API
http://api.cakephp.org/
逆引きリファレンス
Viewテンプレート内で別のテンプレートを呼びたい。
→ libs.view.php View#render($action, $layout, $file) を使う
// 変数の設定 $this->hogehoge = time(); $this->render('yourTemplateName', false);
Session使ってflashMessage
コントローラで
$this->helpers = array(..., 'Session', ...); function myaction(){ $this->Session->setFlash('更新したよ'); }
ビューで
// echoいらない $session->flash()
ページャ、ページング
アクションで
$this->paginate = array('limit' => 20, 'order' => 'hoge'); // $conditionsはfindと同じでよろし $this->paginate('User', $conditions);
ビューで
$paginator->params() で各パラメータ取得。
page: 現在のページ番号
defaults.limit: 1ページあたりの項目数
count: 総項目数
current: 現在ページに何件表示されているか
pageCount: 総ページ数
実際これだけじゃ足りなくて自前実装になる。Zend_Paginatorの方がまだ楽かも。
DBからの取得
CakePHPのモデルは「arrayベース」。全部arrayでやりとりする。Railsのパクりということで、ActiveRecordパターンかと思ったら、なんかそうではなかった。テーブルデータゲートウェイパターンか。
// 一件取得 $data = $this->User->findById($id); // データはこんな風になってる。(モデル名がキーになる二次元配列なので注意!) // $data = array( // 'User' => // array('id' => 1, 'name' => 'akkun', 'gender' => 'male') // ); // gender=maleだけ全件取得 $data = $this->User->find('all', array('conditions' => array('gender' => 'male')));
DBからの取得からの更新
$data = $this->User->findById($id); $data['User']['name'] = 'john smith'; $this->User->save($data);
フォームでPOST
ビューで
$form->create('User', array('url' => '/user/hoge'))
アクションで
if (!empty($this->data['User'])){ // POSTの場合 }
発行されたSQLクエリを見たい
core.php のココを2に。
Configure::write('debug', 2);
ちなみに、
- 0:メッセージ表示しない
- 1: Error,Warningを表示
- 2: 1加え、SQL出力
- 3: 2に加え、コントローラーをダンプ
ビューやコントローラで任意のアクションのrender結果を得る
echo $this->requestAction('users/show', array('return')
http://api.cakephp.org/class/object#method-ObjectrequestActi...
requestActionはObjectが持ってるので、ビューやコントローラに限らず、だいたいどこでも使える。
cakeコマンドを使いたい
# ここにあるのでexportするなりパスを通す cd /my/cake/app_folder ../cake/console/cake [command]
cake bake でscaffolding
前もってテーブルは作っとく。
マイグレーションみたいなことする (cake schema)
cake schema generate # 現在のDB構造をconfig/sql/schema.phpに反映 cake schema run create # schema.phpからテーブルを作成 cake schema run update # schema.phpの状態にDB構造を反映 cake schema run update [table_name] cake schema run update -s 2 # 特定のスナップショット
LIKE検索する
こうすればちゃんとエスケープしてくれる(はず)
LIKEのとこは >= や <= とかでも使える
$params = array(); $params['conditions'][] = array( 'name LIKE' => '%'.$data['name'].'%' ); $users = $this->User->find('all', $params);
joinする
$params = array(); $params['joins'][] = array( 'type' => 'INNER', 'alias' => 'Order1', 'table' => 'orders', 'conditions' => 'Order1.user_id = User.id' ); $params['conditions'][] = array( 'Order1.order_type' => 1 ); $users = $this->User->find('all', $params);
サブクエリを使う
$dbo = $this->User->getDataSource(); $subQuery = $dbo->buildStatement(array( 'fields' => array('Order1.user_id'), 'table' => 'orders', 'alias' => 'Order1', 'order' => null, // 省略できない 'limit' => null, 'group' => null, 'conditions' => array('Order1.order_type' => 1) ), $this->User); $subQuery = 'User.id NOT IN (' . $subQuery . ')'; $params['conditions'][] = $dbo->expression($subQuery); $users = $this->User->find('all', $params);
トランザクションを使う
begin, commit, rollbackはModelクラスに定義されていない。
Overloadableを使って、BehaviorsにdispatchするかそうでなければdataSourceにqueryを渡してるみたいだ。ああ、sqlを直接実行してるのね...。
よって複数モデルにまたがっても問題ない。
$this->User->begin(); $this->User->save(); if ($success){ $this->User->commit(); }else{ $this->User->rollback(); }
モデルのフック
http://book.cakephp.org/view/1048/Callback-Methods
beforeFind(mixed $queryData) afterFind(array $results, bool $primary) beforeValidate() beforeSave() afterSave(boolean $created) beforeDelete(boolean $cascade) afterDelete() onError()
ハック
SecurityComponentのパスワードを平文でソースに書かないようにする
一応動く
function beforeFilter() { // パスワードを平文保存しないハック if (isset($_SERVER['PHP_AUTH_PW'])){ $_SERVER['PHP_AUTH_PW'] = sha1($_SERVER['PHP_AUTH_PW']); } $this->Security->loginOptions = array('type' => 'basic'); $this->Security->loginUsers = array('nsg' => '31f30ddbcb1bf8446576f0e64aa4c88a9f055e3c'); // sha1したパスワード $this->Security->requireLogin('*'); parent::beforeFilter(); }