SplFixedArray, An Underutilized PHP Gem

Arrays in PHP are not arrays per the typical array data type. Instead, as Matt Butcher recently pointed out arrays in PHP are similar to hashes in other languages. This can be a very important point to know when tracking down bugs in code and to programmers coming to PHP from other languages. But, what if we wanted something like a traditional array data type? Maybe something that preserved numeric order. Enter SplFixedArray.

An Example Problem

A simple example of a problem PHP arrays don't handle well is ordering by number. Let's look at a simple example.

$foo = array();
$foo[0] = 'a';
$foo[1] = 'b';
$foo[2] = 'c';

// Remove and replace index 1 with something new.
unset($foo[1]);
$foo[1] = 'what?';

print implode($foo); // prints "acwhat?"

As you can see numeric order on an array is not preserved. What if we wanted to use something that preserved numeric order? Enter SplFixedArray.

// SplFixedArray is fixed in size but it can be altered. 3 is initial size.
$foo = new SplFixedArray(3);

$foo[0] = 'a';
$foo[1] = 'b';
$foo[2] = 'c';

// Remove and replace index 1 with something new.
unset($foo[1]);
$foo[1] = 'what?';

print implode($foo->toArray()); // prints "awhat?c"

The numeric ordering of elements is preserved. SplFixedArray has the ability to be generated from an array and to have an array be generated from it allowing for interoperability.

The Performance and Memory Impact

Something I didn't expect was for SplFixedArray to be faster and use less memory than an array.

Memory usage is does not scale the same for these two. An array with less than 6 items in it will use less or about equal memory than a comparable SplFixedArray object. Once you pass about 6 items SplFixedArray uses less memory. The memory growth rate SplFixedArray is much lower and you can quickly get to the case in large sets where it uses half the memory. This is of course dependent on what's being stored in the array.

Also note, when you use calls like:

$bar = $foo->toArray();

This case has both an array ($bar) and an object ($foo) in memory.

SplFixedArray is faster at getting and setting information. In some basic testing I found it to be better than 25% faster.

Some Catches

There is a catch with SplFixedArray. It's an object not a primitive data type in PHP. Array specific functions like implode() don't work on SplFixedArray. SplFixedArray does implement the Iterator, ArrayAccess, and Countable interfaces making it useful in a lot of situations. But, it's no drop in replacement. Rather SplFixedArray is another useful tool in our quest for better development.