cakephperの日記(CakePHP, MongoDB) Twitter


PHPMatsuri2011開催決定! 10/15(sat), 16(sun) 大阪。
http://2011.phpmatsuri.net/

2012-02-09

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は、下記の機能があります。

2012-02-04

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 独自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


[追記]

Prepared Statementsでバインドした値が、sql_debug画面に出なかったのでパッチ書いて送りました。

CakePHP2.1ブランチで取り込まれました

https://github.com/cakephp/cakephp/commit/e8a9d93eb52cdff15acee789a89e3c569da9b259

2012-02-03

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からプラグインのbootstrapとroutesが読み込める

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

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

詳細は下記。

http://book.cakephp.org/2.0/en/plugins.html

2012-01-20

もっと速いユニットテストを頼む

今やってるプロジェクトのテストケースとテストデータが結構な量あり、私のマシンで実行すると15分以上かかってしまいます。テスト環境は、 VMwareCentOSをゲストOSにして、Windows7をホストOSにしてます。ノートPCは8Gメモリ、5400rpmのHDD。一番の原因は、5400rpmのHDDかつVMwareのゲストOSのディスクI/Oが遅いということです。そのためテストデータ(Fixture)をテストケースごとにリストアしてという動作に時間がかかります。

まずは、HDDIntel SSDに変えてこれを10分以下に短縮できました。SSD快適すぎる。IntelSSDは移行ツールも無料で付いてるので便利です。

SSDで快適にはなりましたが、もっと速くがロマンというもの。また、SSDにディスクI/O発行しまくるのはSSDの寿命を縮めるので精神的に良くないです。(SSDはデータブロックの書き換え回数に上限があるので)

ということで、OS起動時に、MySQLのデータフォルダをメモリに全部載せてしまって、シャットダウンするときにディスクに戻すというアイディアを実行しました。

結論から言うと、テストは5分ぐらいに収まりました!

[追記] phpxdebugはテスト実行中はOFFにしたほうが良いです。 3分ぐらい短縮できました。

メモリに載せるとは、Linuxのtmpfsというメモリファイルシステムの機能を使って(WindowsのRAM diskみたいなやつ)、そこにMySQLデータをmvコマンドで移動させるだけです。CentOSのようなRedhatクローンLinuxだと、標準で/dev/shmというディレクトリがtmpfsとしてマウントされているので、今回はそれを利用します。CentOSに2Gのメモリを割り当てたら、/dev/shmは500Mほどマウントされました。


ちなみに、テストデータは一度バックアップを取っておいて、いつでも吹っ飛んで良いようにします。(OSがクラッシュすると全部消えるので)

/etc/rc.d/init.d/mysql stop
cp -rp /var/lib/mysql /var/lib/mysql-bkup

今回2つのスクリプトを作りました。

  • onMemoryDeploy.sh:
    • DBファイルを/dev/shmに移動させて、/var/lib/mysqlにリンクを貼るスクリプト(その逆の動作も)
  • onMemoryMySQL:
    • CentOSのinit script。 /etc/rc.d/init.d/以下においてOS起動、停止時にonMemoryDeploy.shを実行する

Ubuntuの人とかMacの人はinit scriptを自作して、onMemoryDeploy.shパラメータを変えればいけると思います。


ではまず、onMemoryDeploy.shから。

やっている事は、mysql停止して、tmpfsにデータをmvして、/var/lib/mysqlシンボリックリンクを貼ってるだけです。最初の5行のパラメータを自分の環境用に変更すればうごくと思います。


次に、CentOS用のinit script.


今回は、2つのスクリプトを下記のディレクトリに設置。

/root/onMemoryDeploy.sh
/etc/rc.d/init.d/onMemoryMySQL

そして、起動時に実行されるようにする

/sbin/chkconfig --add onMemoryMySQL
/sbin/chkconfig onMemoryMySQL on

これだけです。Enjoy!


余談

CentOS用のinit scriptで、/var/lock/subsys/onMemoryMySQLにファイルを作っているのは、このファイルが存在しないと停止時に実行してくれなくなるので。実験中は何度かデータ消しました。。。

2011-12-16

求人: エンジニアを探しています

師走ですねー。バタバタしています。

さて、2件ほど案件があって、PHP技術者を探しているので、もし都合のつく方がいればお願いします。

企業/フリーランス問いません。


CakePHPで新規サイト構築

週2日程度で渋谷のオフィスにて作業。

長期案件なので、要件ヒアリング、設計、実装をお任せできる方を探しています。ヒアリング/設計フェースは私がサポートに入ります。

CakePHPで新規サイトを構築する案件なのですが、既存アプリと同じようなDB構成になりそうなので、DBスキーマはある程度ある状態からの開発になります。

ある程度設計からお任せできるので、CakePHP2.0でやってみたいという方などいかがでしょうか?


CakePHPの既存サイトの改修(主に画面周り)

週4日程度で、外苑前エリアにて作業。 2011年12月から2012年2月ごろまでの案件です。

既存のCakePHPサイトですが、Html/CSS/Jsの画面変更がメインになると思います(デザインテンプレートは別の方が作成します)

PHPは簡単な修正ぐらいのレベル。

CakeJsヘルパーは使ってないので、Js(特にjQuery)使える人であれば大丈夫です。

おかげさまで、こちらは決まりそう :)


もし上記のどちらかに興味のある方は、Twitter @cakephper に連絡していただくか、

ichikawayあっとgmailどっとcom

までメールください。