Symfony 1.4+Doctrine
やたら不便(だと個人的には思っている)なDoctrineの、SELECTに関するメモ。
やりたかったことは、ある条件で抽出した複数行に1行ずつ処理を加えて書き戻すというフロー。
fetchArray()とかでは配列しか返ってこないので意味がなく、fetchOne()では先頭行しか返ってこない。
fetchOne()を複数回実行すればいいのかと思ったら無限ループに陥った。
findByではorderByをするのにフックを使わないといけないらしいのでパス。
一応、以下の方法で解決しました。
$collection = Doctrine_Query::create() ->select('u.*') ->from('Users u') ->where('u.flag = ?', '1') ->orderBy('u.id') ->execute(); var_dump(get_class($collection)); // Doctrine_Collection $iter = $collection->getIterator(); var_dump(get_class($iter)); // ArrayIterator while ($record = $iter->current()) { var_dump(get_class($record)); // Users var_dump($record->getId()); $iter->next(); }
next()呼ばないといけないのは面倒だなと思ったら、foreachで使えたらしい。
$collection = Doctrine_Query::create() ->select('u.*') ->from('Users u') ->where('u.flag = ?', '1') ->orderBy('u.id') ->execute(); var_dump(get_class($collection)); // Doctrine_Collection $iter = $collection->getIterator(); var_dump(get_class($iter)); // ArrayIterator foreach ($iter as $record) { var_dump(get_class($record)); // Users var_dump($record->getId()); }
これでかなりマシになった。
最終的にはこれで。
$collection = Doctrine_Query::create() ->select('u.*') ->from('Users u') ->where('u.flag = ?', '1') ->orderBy('u.id') ->execute(); var_dump(get_class($collection)); // Doctrine_Collection foreach ($collection->getIterator() as $record) { var_dump(get_class($record)); // Users var_dump($record->getId()); }
あとはループ内で$record[‘data’] = ‘hoge’;$record->save();とかしておけばOK。
追記:2010/03/30
全然違った。もっと簡単にできました。getIterator不要でした。
foreach ($collection as $record) { $record['data'] = 'hoge'; $record->save(); }
慣れてくると意外と便利な気がしなくもないDoctrine。結合系と特に。