The PHP 5 Iterator interface is very useful for defining custom behaviour for looping over objects, however I just noticed that looping over such objects in Smarty will not work correctly.
Smarty will in fact cast an object back to an array, so when you loop over it, the template will loop over the object's properties (as opposed to using the rules defined by the Iterator methods).
For example, I used code similar to the following to create a class over which I can loop. This lets me loop over the protected $_data array.
class MyClass implements Iterator { protected $_data = array(); public function rewind() { reset($this->_data); } public function current() { return current($this->_data); } public function key() { return key($this->_data); } public function next() { return next($this->_data); } public function valid() { return $this->current() !== false; } public function size() { return count($this->_data); } }
What I want to be able to do is loop over each element in the array with the following code:
{foreach from=$myClassObj item=row}
{$row}
{/foreach}However, this will not work as expected in Smarty. To get around, I implemented as method called getData() which simply returned the array. This meant my template had to look as follows:
{foreach from=$myClassObj->getData() item=row}
{$row}
{/foreach}It's a bit annoying to have to do this, since in some ways it defeats the purpose of the using the Iterator interface, but I guess sometimes small sacrifices need to be made.