PHP5 Iterators + foreach

From: Date: Sat, 31 Jul 2004 16:33:52 +0000
Subject: PHP5 Iterators + foreach
Groups: php.smarty.dev 
Request: Send a blank email to php-smarty-dev+get-2510@lists.php.net to get a copy of this message
Hi all, after the discussions in the IRC channel over the past few days about adding support for iterators to foreach, I worked up the following patch that adds almost complete support for it except for a few specific problems. When you're using foreach properties (like foreach.name.iteration, etc) the last and total properties wont work. This is mostly because you can't use count() on an iterator. This was discussed on the php-dev list a few months back but nothing seems to have become of that. So I submit this now, and hopefully one of the other "smarties" might have a brainwave and find a solution that doesn't involve looping over the iterator twice. And testing with php4 would be nice also :) For my test cases you can see: <http://smarty.lexx.odynia.org/foreach.php> (please no flattening my modem) Special thanks must go to mensi firstly, for requesting this and doing most of the thinking, and messju for his input ;) -bok Patch count be found below, and here: <http://smarty.lexx.odynia.org/Smarty_Compiler.class.php.diff> Index: Smarty_Compiler.class.php =================================================================== RCS file: /repository/smarty/libs/Smarty_Compiler.class.php,v retrieving revision 1.329 diff -u -r1.329 Smarty_Compiler.class.php --- libs/Smarty_Compiler.class.php 27 Jul 2004 17:59:35 -0000 1.329 +++ libs/Smarty_Compiler.class.php 31 Jul 2004 16:26:27 -0000 @@ -1162,8 +1162,13 @@ } if (isset($name)) { - $output .= "{$foreach_props}['total'] = count(\$_from = (array)$from);\n"; - $output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n"; + $output .= "if (function_exists('is_a') && is_a($from, 'IteratorAggregate')):\n"; + $output .= " {$foreach_props}['show'] = {$from}->getIterator()->valid();\n"; + $output .= " \$_from = $from;\n"; + $output .= "else:\n"; + $output .= " {$foreach_props}['total'] = count(\$_from = (array)$from);\n"; + $output .= " {$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n"; + $output .= "endif;\n"; $output .= "if ({$foreach_props}['show']):\n"; $output .= "{$foreach_props}['iteration'] = 0;\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; @@ -1171,7 +1176,16 @@ $output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n"; $output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n"; } else { - $output .= "if (count(\$_from = (array)$from)):\n"; + $output .= "\$_show = false;\n"; + $output .= "if (function_exists('is_a') && is_a($from, 'IteratorAggregate')):\n"; + $output .= " if ({$from}->getIterator()->valid()):\n"; + $output .= " \$_show = true;\n"; + $output .= " endif;\n"; + $output .= " \$_from = $from;\n"; + $output .= "elseif (count(\$_from = (array)$from)):\n"; + $output .= " \$_show = true;\n"; + $output .= "endif;\n"; + $output .= "if (\$_show):\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; } $output .= '?>';

« previous php.smarty.dev (#2510) next »