PEARのDB_DataObject、めちゃくちゃ便利。その前まではPEAR DBを使っていて、PEAR DBも便利だと思っていたけれど、その比ではないね。この便利さは。
というか、実際はPEAR DB+自作マッピング処理をやっていたのだけれど。
しかし、DataObjectにはなく、PEAR DBにある便利な機能がある。それは、プレースホルダである。
$req = "SELECT * FROM hoge WHERE id = ? and disp = ?";
$param = array(100,"on");
$ret = $con->query($req,$param);
みたいな使い方が出来た。?と!の記号部分が自動的にエスケープされ、置き換わるという機能。SQLインジェクションも防げるし、自前でエスケープすると無駄にコード量が増えて、ソースが見づらくなるので、この機能は必ず使っていた。
しかし、DB_DataObjectでは、whereなどの指定に、whereAdd()を使うが、この時点ではエスケープされない。
$table->hoge = $hoge; // これはエスケープされる。
$table->whereAdd("hoge = $hoge");
//これはエスケープされてないのでSQLがエラーになるし、
//SQLインジェクションの危険性あり
なので、普通に考えると、
$table->whereAdd("hoge = '" . addslashes($hoge) . "'");
となる。しかし、シングルクォートの対応とか、addslashes忘れとか、条件が複雑になると、もう分けのわからなコードになってしまう。
そこで、PEAR DBのプレースホルダの代わりになる関数を自作して、パラメータとして渡すことにした。
$table->whereAdd(sql_holder("hoge = ? and fuge = ?",array($hoge,$fuge)));
自動的に?の部分がエスケープされ、置換された結果の文字列が帰ってくるという仕組み。
もしかして、DB_DataObjectに同じような機能が既に実装されて瑠牙、知らないだけだったら、かっこわるいなぁ。誰か教えて。
まだまだDB_DataObjectの解説ページ少ないから、ちょこちょこ載せていこう。