Doctrine_Collectionをループする

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。結合系と特に。


タグ: ,

新しく会社作りました!

コメントをどうぞ