CakePHPの$this->dataの扱い
アマゾンのサーバでエラーが起こっているかもしれません。一度ページを再読み込みしてみてください。
もう随分日が経ってしまってますが、CakePHP勉強会に参加してきました。内容に関してはあちこちで書かれているのでここでは省略。
さて、Shin x blogの新原さんの発表「CakePHPを業務に導入する」で
$this->dataはそのまま使わない
=> 外部から来る値は信用しない
という話があったのですが、この件について書いてみようと思います。
$this->dataをそのままsaveしない
発表後の質疑応答で新原さんは、
formに入力された値を鵜呑みにすると危険。入力フォームで表示していないが存在するフィールドに対しても値が入ってしまう可能性があるので、いきなり$this->dataの値をsaveメソッドに渡さず、別配列に値を渡すなどして、必ず値のチェックをしましょう
という趣旨のことを話されていました。例えば以下のようなユーザーを管理するテーブルが用意されていたとします。
CREATE TABLE users(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
is_admin TINYINT
);
nameがユーザー名、is_adminが管理者を表すフラグとします。
ここで、ユーザーを追加するためnameの値だけ受け取るような入力フォームが用意されているとします。
<?php echo $html->input( ‘User/name’ ); ?>
Controllerでは$this->data['User']['name']に入力された値が入ります。
で、この$this->dataをそのまま$this->User->saveに渡すと値がDBに保存されますが、もし用意したフォーム以外から$this->data['User']['is_admin']に値が渡されていたらどうなるでしょう? 管理者権限が与えられてしまい、場合によってはそのサイトが乗っ取られてしまう可能性もあります。
空の値に注意
もう一つ、自分が遭遇した$this->dataの値をそのまま保存しないほうがいい理由について書いてみます。
例えば、商品を管理するテーブルが用意されているとします。
CREATE TABLE articles(
id INTEGER PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
price INTEGER,
openprice TINYINT
);
nameが商品名、priceが値段、openpriceがオープンプライスかどうかのフラグとします。
これらの3つを受け取る入力フォームを用意します。
<div>商品名: <?php echo $html->input( ‘Article/name’ ); ?></div>
<div>価格: <?php echo $html->input( ‘Article/price’ ); ?></div>
<div><?php echo $html->checkbox( ‘Article/openprice’ ); ?>オープンプライス</div>
さて、オープンプライスの商品を入力しようと思い、価格の値を空欄とします。この時$this->dataの値をそのまま保存するとどうなるでしょうか?
実は新規で保存した場合、価格の値はnullになるのですが、更新した場合は価格の値が0になります。これはUPDATE文でpriceの値に空文字列が渡されてしまうため、このような現象が発生します。
0とnullを区別する必要がない場合はいいのですが、例えばfindの条件でIS NULLを指定したい場合など、このままでは困ってしまうシチュエーションもあります。したがって、saveの前に値チェックを入れる必要があります。
if( empty( $this->data['Article']['price'] ) && $this->data['Article']['price'] != ‘0′ ){
$this->data['Article']['price'] = null;
}
$this->Article->save( $this->data );
?>
文字列フィールドの場合も空文字列として登録されてしまうので、nullと空文字列を区別したい場合は同様の処理が必要です。
まとめ
- $this->dataの値を手つかずでsaveする場合は注意が必要
- 入力フォームに表示していない値が渡ってくる可能性を想定する
- 空の値の正規化をsave前に行う
おまけ
勉強会参加者の中に、家がすぐご近所の方を発見。しかも出身中学が隣だったことも発覚し、軽く衝撃w。そして懇親会で同じテーブルだった方が隣の市にお住まいだったりしてまたびっくり。Web業界って渋谷とか六本木とか、都心の方が盛り上がっているけど、多摩地区も負けてないなぁと思ったりもしました。三多摩IT技術者の会みたいなのが出来たら面白いかもしれませんね。
No comments yet. Be the first.
Leave a reply