Why I don't think type-hinted foreach loops are a good idea
Posted on Tuesday, June 8 2010Tags: php internals
There was a Twitter poll going around this morning that I thought was kind of interesting and got me thinking. It asked whether or not type-hinting in a foreach loop would be a good idea. The argument was that the same arguments that go for have type hinting in functions/methods apply to loops. Those reasons would primarily be structure. Having a more rigid structure means that the likelihood of a runtime error is lessened to a much greater degree. I agree with this statement, but I don't think that it applies to loops. And here's why.
The structure argument makes complete sense in the function/method definition. That is because an individual function has a defined unit of functionality. Therefore, requiring a certain type of data may be necessary to implement that specific piece of functionality.
However, this is not the same with a loop. The only purpose of a loop is to iterate over data. The example given is
foreach($array as $key => MyClass $a)
I am assuming that when you iterate over the array that if an array item is not an instance of MyClass that PHP would fail in the same way that it does when you run into a function with a different declaration. Besides the fact that an array is a generic data structure, what happens if this failure occurs during a series of database inserts or updates? Or a series of web service calls? IMHO, a loop is a generic structure that does one thing: iteration.
That said, there is actually a construct that I would be open to.
foreach(MyCollectionClass $array as $key => $a)
Then you could have code like this
class MyClass {}
class MyCollectionClass extends ArrayIterator
{
public function append($value)
{
if (!$value instanceof MyClass) {
throw new Exception("Invalid class added to collection");
}
parent::append($value);
}
public function offsetSet($index, $newval)
{
if (!$newval instanceof MyClass) {
throw new Exception("Invalid class added to collection");
}
parent::offsetSet($index, $newval);
}
}
What this does is enforce typing prior to the loop iteration and protects against invalid data in the loop. But this could just as easily be written
if ($array instanceof MyCollectionClass) {
foreach( $array as $key => $a) {
}
}
What do you think?
Posted on 6/9/10 5:27 AM
You should control the type when pushing data in the array and not afterwards.
Posted on 6/9/10 6:41 AM
Posted on 6/24/10 11:55 AM
Doing the array cast drastically limits the use of the iteration because it gets binded to a certain type on outbound instead of dealing with proper types on each iteration.
On consequence is that the nice SPL iterator stuff get's broken with such array casts.
I would therefore consider it bad practice in PHP to do casting in foreach.




