Sunday, June 03, 2007

php style: foreach is better

Since it seems that everyone wants to know about reading and writing csv with php, I thought I'd take a moment to push the virtues of the foreach loop.

First: It's neater. Consider that
foreach ($collection as $item) {

}
is a billion times neater than:
for ($i=0; $i<count($collection); $i++) {
$item = $collection[$i];
}

But time and time again, I see the latter used.


Second: What happens if your collection isn't neatly ordered? In this example, the size of the collection is 2, and the for loop will completely miss things. This rarely happens, but can be very frustrating when it does.
$collection = array(1,2,3); unset($collection[1]);
for ($i=0; $i<count($collection); $i++) {
$item = $collection[$i];
}

Third: I cannot think of more than one situation where I've ever had to do anything other that forward-traversal. So why waste time with a for() loop unless you really, really need it. Consider the readability of this code below, and the nightmare people can experience when trying to maintain your code.
This was some code for interacting with an open office document, extending the DOM:
if ($stylesList->length > 0) {
$styles = $stylesList->item(0)->getElementsByTagName('style');

if ($styles) {
//Load styles
for ($i = 0; $i < $styles->length; $i++) {
$style = $styles->item($i);
$name = strtolower($style->getAttribute('name'));
$this->styles[$name] = $style;
}
}
}
and this is the same code, after refactoring:
$nodeList = $this->getElementsByTagNameNS(self::XMLNS_OFFICE, 'automatic-styles');

if (!self::checkNodeList($nodeList)) {
return array();
}

$node = $nodeList->item(0);
$nodeList = $node->getElementsByTagNameNS(self::XMLNS_STYLE, 'style');

if (!self::checkNodeList($nodeList)) {
return array();
}

foreach ($nodeList as $node) {
$name = strtolower($node->getAttributeNS(self::XMLNS_STYLE, 'name'));
$this->styles[$name] = $node;
}
Notice how everything is easier to read, but the level of complexity has increased? Foreach makes life simpler...

Forth: It's faster.

1 comment:

Anonymous said...

Too true!

The for loop is overused, unnecessary, messy and takes longer to type then a foreach loop.

I have always used foreach and the only reason i would need a for is if i needed a incrementing value, so if i need a incrementing value i either use the $key if it's a numerical value or i do a manual increment like so....


$count = 0;
foreach ($foo as $bar)
{
// Do Stuff with count
$count++;
}


Great article, thanks for sharing!