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