++++ Introduction {{Doctrine_Collection}} is a collection of records (see {{Doctrine_Record}}). As with records the collections can be deleted and saved using {{Doctrine_Collection::delete()}} and {{Doctrine_Collection::save()}} accordingly. When fetching data from database with either DQL API (see {{Doctrine_Query}}) or rawSql API (see {{Doctrine_RawSql}}) the methods return an instance of {{Doctrine_Collection}} by default. The following example shows how to initialize a new collection: $conn = Doctrine_Manager::getInstance() ->openConnection(new PDO("dsn", "username", "pw")); // initalizing a new collection $users = new Doctrine_Collection($conn->getTable('User')); // alternative (propably easier) $users = new Doctrine_Collection('User'); // adding some data $users[0]->name = 'Arnold'; $users[1]->name = 'Somebody'; // finally save it! $users->save(); ++++ Accessing elements You can access the elements of {{Doctrine_Collection}} with {{set()}} and {{get()}} methods or with {{ArrayAccess}} interface. $table = $conn->getTable("User"); $users = $table->findAll(); // accessing elements with ArrayAccess interface $users[0]->name = "Jack Daniels"; $users[1]->name = "John Locke"; // accessing elements with get() print $users->get(1)->name; ++++ Adding new elements When accessing single elements of the collection and those elements (records) don't exist Doctrine auto-adds them. In the following example we fetch all users from database (there are 5) and then add couple of users in the collection. As with PHP arrays the indexes start from zero. $users = $table->findAll(); print count($users); // 5 $users[5]->name = "new user 1"; $users[6]->name = "new user 2"; ++++ Getting collection count The {{Doctrine_Collection}} method {{count()}} returns the number of elements currently in the collection. $users = $table->findAll(); $users->count(); // or count($users); // Doctrine_Collection implements Countable interface ++++ Saving the collection As with records the collection can be saved by calling the save method. $users = $table->findAll(); $users[0]->name = "Jack Daniels"; $users[1]->name = "John Locke"; $users->save(); ++++ Deleting collection Doctrine Collections can be deleted in very same way is Doctrine Records you just call {{delete()}} method. As for all collections Doctrine knows how to perform single-shot-delete meaning it only performs one database query for the each collection. For example if we have collection of users which own [0-*] phonenumbers. When deleting the collection of users doctrine only performs two queries for this whole transaction. The queries would look something like: DELETE FROM user WHERE id IN (1,2,3, ... ,N) DELETE FROM phonenumber WHERE id IN (1,2,3, ... ,M) It should also be noted that Doctrine is smart enough to perform single-shot-delete per table when transactions are used. So if you are deleting a lot of records and want to optimize the operation just wrap the delete calls in {{Doctrine_Connection}} transaction. // delete all users with name 'John' $users = $table->findByDql("name LIKE '%John%'"); $users->delete(); ++++ Key mapping Sometimes you may not want to use normal indexing for collection elements. For example in some cases mapping primary keys as collection keys might be useful. The following example demonstrates how this can be achieved. // mapping id column $user = new User(); $user->setAttribute(Doctrine::ATTR_COLL_KEY, 'id'); // now user collections will use the values of // id column as element indexes $users = $user->getTable()->findAll(); foreach($users as $id => $user) { print $id . $user->name; } // mapping name column $user = new User(); $user->setAttribute(Doctrine::ATTR_COLL_KEY, 'name'); // now user collections will use the values of // name column as element indexes $users = $user->getTable()->findAll(); foreach($users as $name => $user) { print $name . $user->type; } ++++ Loading related records Doctrine provides means for efficiently retrieving all related records for all record elements. That means when you have for example a collection of users you can load all phonenumbers for all users by simple calling the {{loadRelated()}} method. $users = $conn->query("FROM User"); // now lets load phonenumbers for all users $users->loadRelated("Phonenumber"); foreach($users as $user) { print $user->Phonenumber->phonenumber; // no additional db queries needed here } // the loadRelated works an any relation, even associations: $users->loadRelated("Group"); foreach($users as $user) { print $user->Group->name; } ++++ Collection expanding