|__ Varien_Data_Collection_Db (C)
|__ Varien_Data_Collection (C)
|__ IteratorAggregate (I)
|__ Countable (I)
You can see that all collection implements two Interfaces IteratorAggregate & Countable. IteratorAggregate is predefined in Standard PHP Library that extends Abstract Base Class Traversable . On using this Interface you can then Iterate Through Object using ”foreach” construct. Countable returns the size of the Collection Object. Among the two Interfaces, IteratorAggregate is particularly important. As you can see in Class Hierarchy both the interfaces are implemented by Varien_Data_Collection concrete class. IteratorAggregate has abstract public method getIterator() which returns the Iterator interface and the concrete Class has to implement the method on its own. It is this Iterator that provides the real iteration functionality. You can get a detailed description about Iterator Here. So if you look into the Varien_Data_Collection you will find the getIterator() implemented like this. [source language=”php”] /** * @class Varien_Data_Collection * Implementation of IteratorAggregate::getIterator() */ public function getIterator() { $this->load(); return new ArrayIterator($this->_items); } [/source] As you can see that it first loads the ”items” (I will get back to this Items) and instanciates the value to an internal Class ArrayIterator . And the Iterator returned by this function can then be iterated using foreach construct. Looks like it is going to be a looonnnnng post, let be summarize what I’ve tried to point out until now. I’ve tried to show the link between the collection class or rather object with the database table and explain the iteration behavior of the collection object. But one question still remains how will the database query’s result transform into a Magento’s ”collection”. This is where the ”items” explanation need to be done. ”Items” are actually array if individual object (item) of the collection which represents the array of tuple of the database query result. As you see in the snippet above the ArrayIterator takes $this->_items are parameter. But $this->_items are not populated here on Varien_Data_Collection but rather on is child class Varien_Data_Collection_Db. Here’s the snippet from Varien_Data_Collection_Db. [source language=”php”] /** * Load data * @class Varien_Data_Collection_Db * @return Varien_Data_Collection_Db */ public function load($printQuery = false, $logQuery = false) { if ($this->isLoaded()) { return $this; } $this->_renderFilters() ->_renderOrders() ->_renderLimit(); $this->printLogQuery($printQuery, $logQuery); // Getting Data from DB $data = $this->getData(); $this->resetData(); if (is_array($data)) { // Looping on each result row foreach ($data as $row) { // Creating Empty "item" Varien_Object’s object $item = $this->getNewEmptyItem(); if ($this->getIdFieldName()) { $item->setIdFieldName($this->getIdFieldName()); } // Setting Varien_Object’s values to that of the row $item->addData($row); /** * Adding the "item" to the collection @class Varien_Data_Collection * So while referring to $this->_items @class Varien_Data_Collection it will return array of this "item" */ $this->addItem($item); } } $this->_setIsLoaded(); $this->_afterLoad(); return $this; } /** * Get all data array for collection * @class Varien_Data_Collection_Db * @return array */ public function getData() { if ($this->_data === null) { $this->_renderFilters() ->_renderOrders() ->_renderLimit(); // Fetching all the row with the Select query set $this->_data = $this->_fetchAll($this->_select); $this->_afterLoadData(); } return $this->_data; } [/source] You can go through the inline comments I’ve added. This is it, I’ve finally worked out the explanation of structure & creation of Magento’s Collection and its iterative behavior. I’ve tried to show pictorially (below) what I have just described. Confused! Plz comment and of course please do comment if I am wrong, because there are “times” when you try to understand things even though they actually aren’t just like you think. I’d like to quote Paulo :“I see the world in terms of what I would like to see happen, not what actually does”!