CakeplusがCakePHP2に対応しました

CakePHPプラグインでよく使いそうなものをまとめたCakeplusがCakePHP2に対応しました。
@k1LoWさんが全ての修正をしてくれたのでマージしただけ。ありがとうございます!

2.0ブランチをご利用ください。
https://github.com/ichikaway/cakeplus/tree/2.0

もしくは下記URLからZipでダウンロードできます。
https://github.com/ichikaway/cakeplus/zipball/cakeplus-0.3.0-for-Cake2


Cakeplusは、下記の機能があります。

CakePHP2 独自SQL文でPrepared Statementを使う

CakePHP1系では、

Model->query('select * from posts where id=?', array('hoge'));

みたいにして擬似バインドできましたが、CakePHP2からは下記の方法でやるとPrepared StatementでSQLを発行してくれます。

// in controller
$result = $this->Post->getDatasource()->fetchAll(
    'select * from posts as Post where Post.id = ? or Post.id = ?', 
    array(1, "abc")
);

$result = $this->Post->getDatasource()->fetchAll(
    'select * from posts as Post where Post.id = :id or Post.id = :id2', 
    array('id'=>1, 'id2' => 2)
);

詳細は下記に。
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#prepared-statements


[追記] 2013/1/29
CakePHP2.1を確認したところ、Model::query()のものは、すべてfetchAll()に渡されるため、擬似バインドではなく、Prepared Statementになってました。
よかった。
Model::query()を使ったほうが記述が楽なので、そっちを使っていれば良いですね。


[追記] 2013/1/28
デフォルトだとキャッシュが効いてしまうので、第3引数にarray('cache' => false)を渡せばキャッシュ無効にできます
http://api.cakephp.org/class/dbo-source#method-DboSourcefetchAll

// in controller
$result = $this->Post->getDatasource()->fetchAll(
    'select * from posts as Post where Post.id = ? or Post.id = ?', 
    array(1, "abc"),
    array('cache' => false)
);

ここで言っているキャッシュとは、1回のアクセスの中でのみ利用されるため、1アクセスで同じクエリが複数回実行されるものに限り有効になります。


[追記]
Prepared Statementsでバインドした値が、sql_debug画面に出なかったのでパッチ書いて送りました。
CakePHP2.1ブランチで取り込まれました
https://github.com/cakephp/cakephp/commit/e8a9d93eb52cdff15acee789a89e3c569da9b259

CakePHP2のセキュリティコンポーネントでCSRF対策のみ行う

CakePHP1のセキュリティコンポーネントは、CSRF対策と、フォーム改竄対策がセットであるため、例えばjavascriptで動的にフォームなどを追加するとチェックに引っかかります。

CakePHP2からは、CSRF対策とフォーム改竄対策がそれぞれオプションでOFFにできます(デフォルトではどちらも有効)


CSRF対策のみ行いたい場合は、コントローラのコンポーネント指定でvalidatePostをfalseにします。

public $components = array(
    'Security' => array('validatePost' => false),
);


動的にON/OFFを切り替えたい場合は、コントローラで下記のようにできます。

$this->Security->validatePost = false; //改竄対応
$this->Security->csrfCheck = false;    //CSRF対応


下記に詳しく書いてあります。
http://book.cakephp.org/2.0/en/core-libraries/components/security-component.html#form-tampering-prevention

CakePHP2からプラグインのbootstrapとroutesが読み込める

app/Config/bootstrap.phpで下記のようにすると読み込めます。

CakePlugin::loadAll(array(
     'FooPlugin' => array('bootstrap' => true, 'routes' => true),
));

詳細は下記。
http://book.cakephp.org/2.0/en/plugins.html

CakePHP2用の自動フォルダ探索プラグイン

CakePHP1では、ControllerやModel以下のphpファイルを階層化するために、その中にフォルダを作って入れても動くのですが、CakePHP2からは自動探索しなくなりました。


例えば、下記のように複数フォルダに分けてファイル管理する場合、

app/Contoroller/Admin/AdminController.php
app/Contoroller/User/UserController.php


CakePHP2では下記のように、bootstrap.phpでApp::build()を使って全てのフォルダを指定しないといけません。

App::build(array(
    'Controller' => array(
        '/app/Contoroller/Admin/', 
        '/app/Contoroller/User/'
    )
));

これってフォルダが増えるたびに定義を増やしていかないといけないので、この処理を自動的に行うプラグインを開発しました。現在はControllerとModelフォルダ以下を探索します。

AutoAppBuild for CakePHP 2.x
https://github.com/ichikaway/AutoAppBuild

インストール方法

gitからプラグインをダウンロードして、下記のように配置します。

app/Plugin/AutoAppBuild

次に、app/Config/bootstrap.phpに下記を記述します。

CakePlugin::load(array('AutoAppBuild' => array('bootstrap' => true)));


これだけです。
本番環境では自動探索じゃなくて、App::build()で定義しておきたいのであれば、

AutoAppBuild::dump();

を実行すると、コピー&ペースト用のApp::build()パスをダンプ出力します。

CakePHP2.0.1がリリースされましたが、ちょっと待ったほうがいい ->2.0.2リリースで解決


CakePHP2.0.1がリリースされましたね
リリースノート
リリースノート(日本語訳)

今回の変更で、HTTPのレスポンスヘッダにcontent-lengthをセットするようになったのですが、そこにマルチバイト関係の不具合があって日本語のコンテンツだとうまく表示できない(途中で切れる)問題があるので、2.0.1は使わずに次のリリースを待つか、最新の2.0ブランチを使うほうが良いです。

[追記]
2.0.2がリリースされ、問題箇所の修正が完了しました。
http://bakery.cakephp.org/articles/lorenzo/2011/11/03/cakephp_2_0_2_released


[追記 終了]

今回の不具合に対して、pullリクエストを2.0ブランチに投げて、何度か議論して無事に取り込まれました。自分のコードがCakeのコアに入るのは初めてなので嬉しい。
https://github.com/cakephp/cakephp/pull/283

githubは、pullリクエスト送った後でも、自分がフォークしてパッチ送ったブランチに追加コミットをpushすると、pullリクエストにコミットを自動追加してくれるみたいです。議論しながら修正コードをpushするだけで良いので、すごく便利でした。


content-lengthを返すようにした経緯は、http1.1でkeep-aliveが効いて、負荷ツールのabコマンドでうまく計測できないというものから来ているようです。(Sergeというツールを使うぶんには問題ないんだけど)
ここでcontent-lengthをmb_strlenでカウントしているためマルチバイトコンテンツだとうまくバイト数が返せない状態でした。ここをstrlen()を使うように変更し、mbstring.func_overload対応も入れたパッチを送りました。
mbstring.func_overloadがphp.iniで2とか7に設定されていると(デフォルト0)、strlen()がmb_strlen()で上書きされている状態になりますので、その場合はmb_strlenでもバイト数カウントするように制御しています。

PHPMatsuri2011に行ってきた!


今年もPHPMatsuriのスタッフとして参加してきました。
チケット販売、ホテルの部屋の手配など、イベント前にやるタスクが盛りだくさんで忙しすぎて、いつも開催前に「絶対来年はやらんぞ」と思ってしまうんだけど、PHPMatsuriが始まると180度転換してしまうから不思議。来年もやったるでーと。

さて、今年のPHPMatsuriも初日のセッション、ワークショップが盛りだくさんなうえに、参加者側から持ち込まれた企画「闇PHPMatsuri」などもあったりして大いに盛り上がりました。2日目のLT大会の前に私は帰ることになってたので、残念ながら参加できませんでした。(山手線のなかで何とかUstreamでLTを見たら、ちょうどGwooのセッションでいきなりあの動画が出てきて吹いたw)

ギャレットとグラハムは、朝まで寝ずにいたみたい。たぶん彼らなりに気を使って質問したい人がいつでも来れるようにそこにいたんじゃないかな。ギャレットのテンションの高さといい、時差ぼけ中なのに夜通し起きてる(しかも前日にむっちゃ飲んでた)体力がすごいと思った。増井さんも夜中までいてTitaniumの質問に答えてた。ファビアンは、自分の講演で出た意見に対して、その後実装してたらしく、ハックデイっぽい過ごし方をした模様。

私個人の成果は・・・ありません。無念。夜中からSocket.ioとNode.jsを触り始めたんだけど、眠い状態でやり始めたのがダメだった。Socket.ioの最新版のAPI仕様が変わったらしく、見つけたサンプルが全然動かずにもがいてました。ちょっと寝て翌朝やったらすぐに解決しました(あるある)。やはり、PHPMatsuriの前には、ある程度の状態を作って、最後の仕上げをそこでやるぐらいのペースが必要ですね。


印象に残ってこと

  • みんなワイワイやってて楽しそうだった
  • 夜中なのにまだ人がたくさん残ってた
  • 関西の参加者は3割ぐらいしかいなかった
  • みんなワークショップ中や、ハックタイムに質問しまくってた
  • 夜中にギャレットが音楽を流してダンスをして、みんなを起こしてた
  • ギャレットが忍者を怖がっていたが、最終的には忍者になってた
  • hiromi2424さんが痩せてなかった
  • 脅威の田中率

最後は写真で振り返ります。


今年もノベリティ満載。ニフティさんのクリップがかわいかった。


Ustream職人がいるので安心。アーカイブVimeoで公開予定です。


ギャレットがTシャツにステッカー貼ったり(Orchestra.ioのTシャツいいな)


最初にやった5分間の雑談タイムでは、すぐにみんなワイワイやってた。


ハッカソンとはなんぞやという説明。去年参加した人は、最初まったりなのを知ってるので遅刻するという説明がw


銅鑼もあります。

吉岡さんの基調講演。これでPHPMatsuriの気持ちが一気に高まります。


セッション中も、ハックスペースでは各自勉強したり、コード書いたり。


講演と同時平行でワークショップも開催。Lithiumの使い方を説明中


増井さんの講演。Titaniumの話や、今の会社に入るまで、入ってから、英語についてなど、面白かった。


Symfonyユーザグループの人たちがSymfony2のワークショップを開催。


グラハムさんの講演。CakePHP2.0の話、Candycane、ドキュメントの話など。


賞品盛りだくさん。


わったい菜さんからのスイーツ差し入れ。すごい量


Symfony2の話聞きたかったけど、Cakeのワークショップに出たので聞けなかった。動画アーカイブが公開されたら聞こう


ギャレットさんのコードの品質に関する発表。


パーフェクトじゃないから、がんばって目指そう!


Masa-PさんのCake辞典を読みながら、「I know this code」とつぶやいてた


夕食後、すぐに自分でビール買ってきて始めちゃう。。。


みんなにビールを強要してたので、みんな飲み始める(自分も含めて)


こんな感じで初日のハックスペースは人がたくさんいて、もくもくとコード書いてる人がたくさん


スポンサーセッション。ニフティクラウドの話


スポンサーセッション。Voyageグループの話


スポンサーセッション。ディノさんのphper.jpの話


テストワークショップは大勢の人がいて、4時間ぐらいずっとやってた。なんか熱気がすごい


テストワークショップのBehatのお話。


闇PHPMatsuriが22:30から開始。発表者は17人ぐらいいた。ネタは何でもあり。


なんか、忍者4人が銅鑼ならしたり、

発表が終わると切りつけたり。。。大いに盛り上がりました



海外ゲストも発表。最後は切られてた。。。


夜からはアングリーバードが大画面で。。。ハッカソンといえばゲームタイム


アングリーバードの様子も配信されてる・・・


アングリーバードをやってるそばで、みんな真面目に開発するというシュールな光景


ビールの缶がたくさん。質問にみんなで議論して答えている様子


会場の外もハックスペースに!


1:30AM ごろの様子。まだまだ残ってますね。


4:00AM ごろに、この動画を流してノリノリで踊る人


5:00AMごろ。あまり人が減ってない!


こんな感じで盛り上がった2日間でした。その後、phpmatsuriの参加者たちはギャレットがしきりに流してたEpic Sax Guyの中毒になってました。

更新履歴

[twitter:@brtriver]さんからEpicSaxGuyの動画が10時間バージョンじゃないという指摘を頂き、修正しました。ご迷惑をおかけして大変申し訳ありませんでした。