Use placeholder in Model::query() of CakePHP

I’m using CakePHP1.2.3

Model::query() is very useful for writing SQL statements as follow.

<?php

$this->Model->query("SELECT `Post`.`id` FROM `posts` AS `Post` WHERE `Post`.`id` = 100", $cachequeries = false);

To avoid SQL Injection, we want to use placeholders instead of embedding user input value in the statement.
We use “?” character in the SQL statement, set array data in 2nd parameter of the query method.
If 2nd parameter is array data in query method, it executes DboMysql::value() for escape value, using the “mysql_real_escape_string” function.

<?php

$sql = "SELECT `Post`.`id` FROM `posts` AS `Post` WHERE `Post`.`id` = ? LIMIT ?";
$this->Model->query($sql, array(100,1), $cachequeries = false);

Cake constructs a SQL statement and executes as follow.

SELECT `Post`.`id` FROM `posts` AS `Post` WHERE `Post`.`id` = 100 LIMIT 1

References
http://book.cakephp.org/view/456/query
http://en.wikipedia.org/wiki/SQL_injection

4 Responses to “Use placeholder in Model::query() of CakePHP”

  1. Jamie Says:

    This may be a silly question, but why are you using Model::query() instead of Model::find()?

  2. ichikaway Says:

    Hi, Jamie. Thank you for your comment.
    I read your blog, it’s so nice:)

    There are few cases to use Model::query().
    I like Model::find() and use it in many cases.

    When I have to construct a complicated SQL statement, sometimes it’s easy for me to write SQL statement using Model::query() ,instead of Model::find().

  3. gothedistance Says:

    Hi Jamie,ichikaway

    I also using Model::query() to construct complicating sql(especially subquery and case-when statement). Coz it’s simply faster than arrange conditions for Model::find(). I realize how can I get expected datas by using sql not Model::find().

    insert or update, I almost use model::save() or updateAll().

  4. ichikaway Says:

    Hi, gothedistance
    Thank you for your comment.
    Maybe, you are thinking what I’m thinking about a use-case of Model::query().

    I often use updateAll(), it’s convenient.
    The updateAll() does not escape the fields, so be cautious when using it.
    http://teknoid.wordpress.com/2009/08/06/save-now-sanitize-later/

Leave a Reply