CakePHPハンズオン@tokyoに参加してます
本日、ウノウにてCakePHPハンズオン@tokyoが開催されております。
最近、「ちょっとした軽いのをぱぱっと作るにはやっぱりPHP便利だよなー」とPHP再評価フェーズに入っているので参加しています(現在進行形)。
以前は自作の俺俺フレームワークでせこせこと組んでいたんですが、今からまたPHPやるならちゃんとしたフレームワーク使うべきだよなと。symfonyが合うような場面だと、今の自分としてはむしろPHPじゃなくてPerlを使いたいので、それならCakePHPが合うんじゃないかなと期待して参加しました。
会場は、ノートPC持参で集まって、公式の CakePHPブログチュートリアル をこなしながらid:yandodさんのお話を聞くという流れ。
リアルタイムのメモなので、粗いのと、個人的な感想を交えているので読みにくいかも知れないけど、そのへんは勘弁。もう懇親会に行ので内容も全く確認できてないけど上げちゃう。
■DB定義
DBスキーマのファイルはapp/config/sql/に置いたけど、それがデファクトということでもないらしい。
SESSIONとかACL管理など、Cakeが提供する機能のためのテーブルが定義されているのであって、アプリケーションで使用するスキーマを置く場所として用意されているわけではないそうな。基本的には「好きなところに置け」ってスタンスらしい。
■Scaffold
公式チュートリアルから少し離れた内容。
app/controllers/posts_controller.php
<?php class PostsController extends AppController { //var $name = 'Posts'; var $scaffold; }
これでデフォルトのScaffoldが動く。
1.2からModelを作らなくてもScaffoldが動くようになった。
$nameの定義はPHP4対策なので5なら不要。
■通常の実装
<?php class PostsController extends AppController { public function index() { $this->set('posts', $this->Post->find('all')); } }
Controllerをこうしておいて、Viewを作らずにブラウザから見るとエラーを出してくれる。
こういう、エラーメッセージでユーザーを導くやり方は面白いよね。
ちゃんと検証してないけど、setした時点でHTMLエスケープしてくれるっぽい。(08/24訂正)setしただけではエスケープされてませんでした。ヘルパーがエスケープ処理をしてくれてました。
$this->getは無かった。Viewに渡した値をControllerでもう一度取るのはどうするのかな。
発行したSQLも合わせて表示してくれるんだけど、
SELECT `Post`.`id`, `Post`.`title`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `posts` AS `Post` WHERE 1 = 1
「WHERE 1=1」はキモい。
POST値はControllerの$this->dataで拾える(GET値は入らないみたい(?))。
Controllerに渡ってきた諸々の情報は、$this->paramsから取れるのかな。
フォームの要素はヘルパー使って出力するとエラーメッセージもよしなにやってくれるから、手書きよりヘルパー使った方がいい。
エラー時に <input class="form-error" 〜/> てな具合にエラーのクラスも吐いてくれるのは嬉しい。
■サンプルに不具合が見つかった件
Controllerで、
public function edit ($id = null) { $this->Post->id = $id; if (empty($this->data)) { $this->data = $this->Post->read(); } else { if ($this->Post->save($this->data['Post'])) { $this->flash('Your post has been updated.', '/posts'); } } $this->render('add'); }
てな具合にeditを実装した場合、editフォームでエラーを発生させて、その後POSTするとIDが取れなくなって、updateじゃなくてinsertが走ってしまう。
時間がないので、この場はスルー。解決策はid:yandodさんがまた出してくれるはず。
IDもPOSTするのか、フォームのactionを書き換えるのか。
フォームのactionがURLを引き継ぐようなやり方が綺麗な気がするけど、そういう機能はあるのかな。
■ルーティング
/app/config/routes.php で制御する。
■コードシュガー
e(h($hoge)) → echo htmlspecialchars($hoge, ENT_QUOTES)
実は最近までENT_QUOTESされてなかったらしい…
a('one', 'two', 'three') → array('one', 'two', 'three') aa('hoge', 'foo', 'bar', 'oge') → array('hoge' => 'foo', 'bar' => 'oge')
後者はよろしくないんじゃないか?
■ControllerからModelを呼ぶ
var $users = array('Model1', 'Model2', ...);
■Modelのテーブル変更
class User extends AppModel { var $useTable = 'user_account'; // 好きなテーブル名を使う var $primaryKey = 'login_id'; // Pkeyも好きなカラム名に }