2010/06/27

PHP cast as array

PHP is full of shenanigans.  If you know them you can code more efficiently.  If you don't it can make for a mess.  One of the lesser used, but useful tricks is casting as array.

If you're not familiar with casting, check the docs:  http://php.net/manual/en/language.types.type-juggling.php

Here's a quick breakdown of what happens when you cast to array:

class TestIterator implements IteratorAggregate {
    public function getIterator() {
        return new ArrayIterator(array(1,2,3));
    }
}

$test_iterator = new TestIterator;

var_dump((array)false);          # array(0) {}
var_dump((array)null);           # array(1) { [0]=>  bool(false) }
var_dump((array)0);              # array(1) { [0]=> int(0) }
var_dump((array)"");             # array(1) { [0]=> string(0) "" }
var_dump((array)array());        # array(0) {}
var_dump((array)new StdClass);   # array(0) {}
var_dump((array)$test_iterator); # array(0) {}

foreach ($test_iterator as $num) { echo "$num\n"; }
> 1
> 2
> 3

The interesting bits here are that null, empty array and empty object all cast to empty array. Even an Iterator. Since the Iterator object is empty is casts to an empty array, even though iterating through it will produce 3 elements. Any other value casts to an array with a single element that is the value.

There's a couple use cases I'd like to highlight from this list. Flexibility in signature params, and easier iteration:

function string_replace($string,$elements) {
    foreach((array)$elements as $element) {
        $pos = strpos($string,'?');
        if ($pos !== false) {
            $string = substr_replace($string,$element,$pos,1);
        }
    }
    return $string;
}
This is just a simple function for replacing question marks in a string with supplied string(s). By casting $elements as an array we can take a single param or an array of params without checking for it in our code. We can also passively return the string untouched if null params are supplied.
echo string_replace('oh ?','hi');
echo string_replace('? ? at swingers', array('meet', 'me'));