Skip to content

Use CakePHP 2's updateAll() Method with Caution!

2 min read

I’ve recently noticed a number of people trying to use CakePHP 2’s updateAll() method very badly.

Let’s first get one thing straight: updateAll() is not the intended way of updating a record in CakePHP, use save() for that!

In many of the cases I’ve seen recently save() would have been a more suitable choice for saving the data. As long as you pass the record’s primary key in the save data, or set the model’s ID before saving, save() will act as an UPDATE rather than an INSERT:-

$this->Model->id = $id;

If you are using updateAll() then caution needs to be taken as it requires you to manually quote strings. The official docs state that

Literal values should be quoted manually using DboSource::value().

A lot of people seem to miss this point. What it means is that any value you pass to updateAll() that is a string needs wrapping in quotation marks. One of the easiest ways of doing this is with the datasource’s value() method:-

$db = $this->Model->getDataSource();
$value = $db->value($value, 'string');

It is never a good idea to just pass $this->request->data to updateAll() as someone could attempt to inject SQL into your query. Only ever pass values that you are in control of. In other words don’t do this:-

// Do not do this
    [ // Some conditions ]

Do this instead:-

$db = $this->Model->getDataSource();
    ['value' => $db->value($this->request->data['Model']['value'], 'string')],
    [ // Some conditions ]

As save(), saveMany() and saveAssociated automatically wrap literals in quotation marks they are usually the preferable choice when saving data. Personally I’ve had little need to use updateAll() in my time developing with Cake. When I have used it it has been to quickly update a field for many rows rather than updating whole records as I have seen people doing.

© 2024 Andy Carter