PDOでPrepareすれば殆ど作業が簡単に片付くが、やっぱりO/R mapperで楽をしたいなと思った。
いろいろ見てみると、
- PropelのPDO版 Propel 1.3
- SeasarのPHP版 S2Container.PHP5
- CybozuのCBL CBL ActiveRecord
- Zend FrameWork Zend_Db
が見つかった。Zend_DbはAPIが固定されてきたけど。arrayがいっぱい出てきて好きじゃない。SeasarはJavaの移植なので設定XMLとか面倒くさそうなのでパス。Propelは普段使ってるからよく知ってる。CybozuのCBLを試してみた。
使い方は、日本語ドキュメントがシンプルでわかりやすい。
http://31tools.com/cbl_activerecord/README.ja.utf8.html
ただ、PostgreSqlの7.xで使うといくつか修正が必要だった。
`{$this->table}`
の箇所で、バッククォートがあると、どうも動作しない。なのでバックォートを全部削除。
次に、SORTが気に入らないので修正。そのままではDESCが指定できないっぽい。
@341行目 if( @$params['order'] ) { $sql .= " ORDER BY {$params['order']}"; + if(@$params['order_type']){ + $sql .= " {$params['order_type']} "; + } }
CBL ActiveRecordはシンプルなので弄って組み込みやすいので手に馴染みそう。
ただ、まだ不満があって
Propelとか使ってるとできること
$c = new Criteria(); $c->add( ArticlePeer::CreatedAt, date("Y-m-d",-60*60*24*30) ); $c->add( ArticlePeer::AuthorId, 10 ) $c= ArticlePeer::doSelectOne($c);
DB_DATAOBJECTならこんな感じだったか。。数年使ってないので忘れた
$article = new Article(); $article->created_at = date("Y-m-d", -60*60*34*30); $article->author_id = 10; $article->find(true);
CBL ActiveRecord
だけど、DB_DATAOBJECT同じようにすると動かない。ANDの複数条件がうまくセットできないみたい。
$article = new Article(); $article->created_at = date("Y-m-d", -60*60*24*30); $article->author_id = 10; $article->find_all();#うまく動作してくれない ####CBL ActiveRecordではこのようになるみたい#### $article = new Article(); $conditions["created_at"] = date("Y-m-d", -60*60*24*30); $conditions["author_id"] = 10; $cond = array(); foreach($conditions as $key => $val) { $cond["condition"][] = "{$key}={$val}"; } $cond["condition"] = implode(" AND ", $cond["condition"]); $article->find_all($cond);#動作する
CBL ActiveRecordだと、結局implode( " AND", $array)でSQLを書かなきゃだめっぽい。なにか良い方法があるのだろうけど、ちょっとわからなかった。PDOならZend FrameWorkのZend_Db使えって事ですかね。
ソースよんでて思った事。
なぜPDO::FETCH_CLASS/FETCH_OBJECTを使わないんだろう。
PDO#query ( string statement, int PDO::FETCH_CLASS, string classname, array ctorargs );
PDOStatement#fetchObject ( [string class_name [, array ctor_args]] );
超便利なんだけど。あまり見かけない。処理的に重いのかな。富豪プログラマだとかLAZYに行こうよ見たいな記事をたまに見かけるのだけれど、不精するならFetchObjectが最高なんだけど。なんでこれじゃだめなんだろう。
class Article { public function getAuthor(){ $stmt = $this->pdo->prepare("SELECT * from author where id = ? "); $stmt->exec(array($this->author_id)); return $stmt->fetchObject("Author"); } } $stmt = $this->pdo->prepare("SELECT * from article where created_at = ? "); $stmt->setFetchMode( PDO::FETCH_CLASS, "Article"); $stmt->exec(array(date("Y-m-d", -60*60*24*30))) $articles = $stmt->fetchAll(); foreach($articles as $article){ $author = $article->getAutor(); }
こんな感じで簡単にObjectつくれるみたいなのだけど・・・・