CodeIgniter+MySQLでデータ全件が更新される?!
5月 29th, 2007 by cilab
少し前にの公式フォーラムで話題になっていましたが、CodeIgniterのActiveRecordには、うっかりすると恐ろしい結果を招く仕様(バグ?)があるようです。
PHP Community Magazine に関連記事がありました。
その記事の内容の要約です:
こんな列のテーブル(テーブル名:users)があったとします。
- user_id
- username
- password
ここで、以下のようなコードを実行したとします。
$data = array('password' =>$new_password);
$this->db->where('user_id', $user_id);
$this->db->update('users', $data);
実行されるSQLは、こんな感じになります。
UPDATE users set password='{$new_password}' where user_id='{$user_id}';
ところで、$user_id が null だった場合、どんなSQLが生成されるでしょうか?
UPDATE users set password='{$new_password}' where user_id='';
UPDATE users set password='{$new_password}' where user_id Is Null;
おそらく上記のどちらかのような感じになると期待することが多いのではないでしょうか。ところが、実際には、下記のようなSQLが生成されてしまいます。
UPDATE users set password='{$new_password}' where user_id;
user_id の後に何もつかないSQL文になります。PostgreSQLなどのDBMSでは、エラーになり、これは実行されません。ところが、MySQLの場合、悲惨なことに、全件のデータ(ここではパスワード)が、更新されてしまうという恐ろしい結果になります…
CodeIgniter1.5.3で実際にテストして動かしてみましたが、指摘の通りの結果になりました。
普通は、ActiveRecordクラスに渡す前に値のチェックを行っていることが多いと思うので、起こりにくい現象ではありますが、うっかりnullチェックが抜けると、大変なことになってしまうので、皆さんも注意してください。
PHP Community Magazineの記事:
http://community.phpmagazine.net/2007/04/bad_experience_with_codeignite.html