Introduction: Making Large Collections Manageable in Magento
Magento collections are basically a large model that contains other models; it basically groups the models together. When collections are small, they can be easily accessed and managed, but when they grow in size, you need to formulate a method to manage them.
For example, you want to change the first letter of your customer's name to capital. Here's a regular method that you would adopt in such a case.
$customers = Mage::getModel('customer/customer')->getCollection()->addAttributeToSelect(array('firstname'), 'inner');
foreach ($customers as $customer) {
$customer->setFirstname(strtoupper($customer->getFirstname()));
$customer->save();
}
When dealing with small collections, you can use this method with ease. But, if you try and apply the same code for the bigger collections, then you will see that the script runs out of memory space leaving you to face this error message:
"Fatal error: Allowed memory size of X bytes exhausted (tried to allocate X bytes) in magento_site\lib\Varien\Data\Collection.php on line 550".
Collection as has been mentioned earlier is an array of all the objects. As and when you add some object to this list, the array grows bigger which is why the collection becomes big and unmanageable.
How to Make Collections Manageable?
You will need to implement the MAGE_CORE_MODEL_RESOURCE_ITERATOR model. With this model, you will be able to get the data from the database one at a time. The method walk() requires two parameters for proper functioning- collection query string and callback method(s). Let's look at how the method is implemented
{
$stmt = $this->_getStatement($query, $adapter);
$args['idx'] = 0;
while ($row = $stmt->fetch()) {
$args['row'] = $row;
foreach ($callbacks as $callback) {
$result = call_user_func($callback, $args);
if (!empty($result)) {
$args = array_merge($args, $result);
}
}
$args['idx']++;
}
return $this;
}
In the above code, a query string that is provided is first executed, and then the results are fetched one after the other, and each result is then sent to the callback method. The result thus sent to the callback method is stored in $args. You can access the data in the callback function with $args[‘row']
Let's see how the code would appear when the iterator mentioned earlier is used
public function uppercaseAction()
{
// get customer collection
$customers = Mage::getModel('customer/customer')->getCollection()->addAttributeToSelect(array('firstname'), 'inner');
// call iterator walk method with collection query string and callback method as parameters
Mage::getSingleton('core/resource_iterator')->walk($customers->getSelect(), array(array($this, 'customerCallback')));
}
// callback method
public function customerCallback($args)
{
$customer = Mage::getModel('customer/customer'); // get customer model
$customer->setData($args['row']); // map data to customer model
$customer->setFirstname(strtoupper($customer->getFirstname())); // set value of firstname attribute
$customer->getResource()->saveAttribute($customer, 'firstname'); // save only changed attribute instead of whole object
}
First you define a collection, and then using the walk method, you will pass the sql query to the iterator. The iterator will then execute the query that has been passed, and eventually call the customercallback() on individual rows of the database. In this callback method, you will first need to instantiate customer model, map the data from $args[‘row'] to the model in question and finally change the first letter of the first name to upper case. When saving, don't use classic save method. Instead save individual attributes using the saveAttribute() method so that you don't run out of memory space.
Conclusion
Large collections that contain numerous models can get difficult to manage. Also they eat into your memory space thus slowing down your store. if you want to save your store from going slow, try to use the iterator Mage_Core_Mode_Resource_Iterator in the code to call the queries individually and execute them one by one.
Deepa, a technical writer with Semaphore Software, who now devotes her time in advising its clients to hire certified magento developers. She offers information as well as tips and latest trends in this domain. Her love for reading helps her constantly provide latest information on different technical and design aspects of Magento


