Stop Reinventing Data Structures: PHP's SPL Already Has What You Need cover image

Stop Reinventing Data Structures: PHP's SPL Already Has What You Need

Scott Keck-Warren • June 12, 2026

A few years ago, I needed a queue. Nothing fancy, just a list of tasks that my script would process one at a time in the order they came in. First in, first out. Classic queue behavior, so I knew I was going in the right direction.

So I built one from scratch. I wrote a class, wrapped a PHP array, added push() and pop() methods, wrote some tests, and called it done. Took me a couple of hours, and I was pretty proud of it.

Then I was reading through the PHP docs for something unrelated and stumbled across SplQueue. A built-in, battle-tested queue class that ships with PHP, sitting there since PHP 5.1. I'd spent two hours rebuilding something that already existed, and the PHP version handled things mine didn't.

What SPL Actually Is

SPL stands for Standard PHP Library, and it's a collection of data structures, iterators, and utility classes that ship with PHP. There's no Composer package, install step, or configuration we get them "for free".

Most PHP developers know about ArrayObject or have bumped into SplFileInfo when working with the filesystem. The data-structure side of SPL is often ignored. We reach for arrays for everything because arrays in PHP are flexible and familiar, and that's usually fine until you need something with actual queue or stack semantics.

SPL includes:

All of these come up in real work more than you might expect.

The Queue Problem

Here's how most of us handle a queue with a plain PHP array.

$queue = [];

// Add items
array_push($queue, 'task-one');
array_push($queue, 'task-two');
array_push($queue, 'task-three');

// Process in order
while (!empty($queue)) {
    $task = array_shift($queue);
    echo "Processing: $task\n";
}

This works, and I'm not going to pretend it doesn't, but there are real problems hiding in that array_shift call.

When you call array_shift, PHP removes the first element and then re-indexes the entire array. If your queue has 10,000 items, that's 9,999 index rewrites per item you process. For a small queue, it's invisible, but for a large one, it will slow you down in ways that are genuinely hard to diagnose.

The other issue is semantic. array_push and array_shift don't communicate intent. Someone reading that code has to think about it for a second to understand you're building a queue. And if they're new to the codebase (or if you're coming back to it six months later), that second adds up.

SplQueue Does This Better

The SplQueue version:

$queue = new SplQueue();

// Add items
$queue->enqueue('task-one');
$queue->enqueue('task-two');
$queue->enqueue('task-three');

// Process in order
while (!$queue->isEmpty()) {
    $task = $queue->dequeue();
    echo "Processing: $task\n";
}

enqueue adds to the back and dequeue pulls from the front. Anyone reading that code knows you're working with a queue without having to think about it.

The performance difference is real, too. SplQueue is backed by a doubly linked list, so enqueue and dequeue are both O(1) regardless of queue size. Each operation touches exactly one node and moves on.

You also get useful methods like count(), isEmpty(), bottom() (peek at the front without removing it), and top() (peek at the back), so PHPstan can find bugs faster. On top of that, the whole thing is iterable, so you can foreach over it without destroying the contents.

Every Custom Implementation Is Debt

When you write a custom class to handle something, you own it. This means that your version needs tests, documentation, and, most importantly, maintenance when a teammate finds an edge case you missed. You're paying that cost for something PHP already solved and is rock solid.

Arrays are genuinely great for most things, and you don't need SPL when a plain array does the job cleanly. But when you find yourself naming a class Queue or Stack or PriorityList, check SPL before you write a single method. There's a good chance the implementation already exists, and you can spend that time on the part of the problem that's actually specific to your application.

A Quick Look at the Others

SplStack works the same way as SplQueue but in reverse order (last in, first out). Push with push(), pull with pop(). Good for undo stacks, backtracking algorithms, or processing nested structures.

SplMinHeap and SplMaxHeap are the ones I'd say are most underused. If you've ever written a priority queue manually, you know how annoying it is. With SplMinHeap, you insert() items and extract() always gives you the smallest one. Flip to SplMaxHeap for the largest. That's it. No custom sorting, no array manipulation.

SplFixedArray is worth knowing about for memory-sensitive scripts. If you know you need exactly 10,000 slots and won't need to resize, a fixed array uses roughly a third of the memory of a standard PHP array at that scale. That's a niche use case, but the savings are significant when it applies.

Check SPL Before You Build

Next time you're about to write a data structure from scratch, check SPL first. The PHP docs cover the full class list, and the examples are straightforward. You can read through the whole thing in fifteen minutes.

It's also worth doing a quick scan of your existing codebase. If you find a custom queue, stack, or sorted list class in there, there's a decent chance it can be swapped for an SPL equivalent with a few renamed method calls and cleaner semantics throughout.