SPL Data Structures

Ma Mariya Vinciya Updated 21 Oct 2026
6 min read ·Lesson 173 of 174
In this post

What Are SPL Data Structures? In simple terms: PHP's array is a Swiss Army knife — it works as a list, a dictionary, a stack, and a queue. But some tasks have a better-suited tool: a stack for undo hi

What Are SPL Data Structures?

In simple terms: PHP's array is a Swiss Army knife — it works as a list, a dictionary, a stack, and a queue. But some tasks have a better-suited tool: a stack for undo history, a queue for jobs processed in order, a priority queue for urgent tasks first, or a heap for always finding the smallest value quickly. The Standard PHP Library (SPL) provides these structures as ready-made classes.

Technically: SPL (always available) includes data structure classes such as SplStack, SplQueue, SplDoublyLinkedList, SplPriorityQueue, SplMinHeap, SplMaxHeap, SplFixedArray, and SplObjectStorage. Each has well-defined behavior and performance characteristics, and they are objects — they can be passed around, type-hinted, iterated, and counted.

Overview

ClassBehaviorTypical Use
SplStackLast in, first out (LIFO)Undo history, navigation history, parsing
SplQueueFirst in, first out (FIFO)Job queues, breadth-first processing
SplPriorityQueueHighest priority firstTask scheduling, support tickets
SplMinHeap / SplMaxHeapAlways gives the smallest / largest elementTop-N problems, shortest delivery times
SplFixedArrayFixed size, integer indexes onlyLarge numeric datasets with lower memory use
SplObjectStorageObjects as keys (sets and maps)Tracking objects, attaching data to objects

 


SplStack: Last In, First Out

<?php
$undo = new SplStack();

$undo->push('Typed "Hello"');
$undo->push('Made text bold');
$undo->push('Deleted paragraph');

echo "Undo: " . $undo->pop() . "\n";
echo "Next undo would be: " . $undo->top() . "\n";
echo "Remaining actions: " . count($undo) . "\n";

foreach ($undo as $action) {
    echo "  $action\n";
}

 

Output

Undo: Deleted paragraph
Next undo would be: Made text bold
Remaining actions: 2
  Made text bold
  Typed "Hello"

 

  • push() adds to the top; pop() removes and returns the top element; top() reads it without removing.
  • Iterating a stack goes from top to bottom — the most recent action first.
  • Calling pop() or top() on an empty stack throws a RuntimeException; check isEmpty() first.

SplQueue: First In, First Out

<?php
$printJobs = new SplQueue();

$printJobs->enqueue('Invoice #501');
$printJobs->enqueue('Invoice #502');
$printJobs->enqueue('Packing slip #501');

while (!$printJobs->isEmpty()) {
    echo "Printing " . $printJobs->dequeue() . "\n";
}

 

Output

Printing Invoice #501
Printing Invoice #502
Printing Packing slip #501

 

Jobs are processed in the order they arrived. dequeue() removes the element at the front in constant time; with an array, array_shift() must re-index the whole array on every call, which becomes slow for large queues.


SplPriorityQueue: Most Important First

<?php
$tickets = new SplPriorityQueue();

$tickets->insert('Password reset request', 10);
$tickets->insert('Website is down', 100);
$tickets->insert('Typo on About page', 1);
$tickets->insert('Payment failed for order 501', 50);

while (!$tickets->isEmpty()) {
    echo $tickets->extract() . "\n";
}

 

Output

Website is down
Payment failed for order 501
Password reset request
Typo on About page

 

  • insert($value, $priority) adds an element with a priority; extract() always returns the element with the highest priority.
  • Internally, a heap keeps insertion and extraction fast (logarithmic time), even with many elements.
  • The order of elements with equal priority is not guaranteed. If ties must be processed in arrival order, use a compound priority such as [$priority, -$sequenceNumber].

Heaps: Always the Smallest or Largest

<?php
$deliveryMinutes = new SplMinHeap();

foreach ([45, 12, 30, 5, 60, 18] as $minutes) {
    $deliveryMinutes->insert($minutes);
}

echo "Fastest three delivery partners: ";
for ($i = 0; $i < 3; $i++) {
    echo $deliveryMinutes->extract() . ' min ';
}
echo "\n";

 

Output

Fastest three delivery partners: 5 min 12 min 18 min 

 

SplMinHeap always extracts the smallest value; SplMaxHeap the largest. For complex elements, extend SplHeap and implement compare():

<?php
final class CheapestProductHeap extends SplHeap
{
    protected function compare(mixed $a, mixed $b): int
    {
        return $b['price'] <=> $a['price'];   // smaller price = higher in the heap
    }
}

$heap = new CheapestProductHeap();
$heap->insert(['name' => 'Desk Lamp', 'price' => 1299]);
$heap->insert(['name' => 'Gel Pen', 'price' => 20]);
$heap->insert(['name' => 'Notebook', 'price' => 60]);

echo $heap->top()['name'] . "\n";

 

Output

Gel Pen

 

compare() returns a positive number if $a should come before $b. Heaps are ideal when you repeatedly need "the next smallest/largest" while elements keep arriving — fully sorting the data each time would be wasteful.


SplFixedArray: Fixed Size, Integer Indexes

<?php
$hourlyVisits = new SplFixedArray(24);

$hourlyVisits[9] = 120;
$hourlyVisits[13] = 340;

echo "Size: " . $hourlyVisits->getSize() . "\n";
echo "13:00 visits: " . $hourlyVisits[13] . "\n";
var_dump($hourlyVisits[0]);

try {
    $hourlyVisits[24] = 5;
} catch (RuntimeException $e) {
    echo get_class($e) . ": " . $e->getMessage() . "\n";
}

 

Output

Size: 24
13:00 visits: 340
NULL
RuntimeException: Index invalid or out of range

 

  • The size is fixed at creation (it can be changed explicitly with setSize()), and only integer indexes from 0 to size−1 are allowed.
  • Unset positions contain null.
  • Because it stores values in a simple contiguous block, it uses noticeably less memory than an equivalent PHP array for large numeric datasets.

SplObjectStorage: Objects as Keys

Arrays cannot use objects as keys. SplObjectStorage can — making it a set of objects or a map from objects to data:

<?php
final class Customer
{
    public function __construct(public string $name) {}
}

$asha = new Customer('Asha');
$bala = new Customer('Bala');

$loyaltyPoints = new SplObjectStorage();
$loyaltyPoints[$asha] = 120;
$loyaltyPoints[$bala] = 45;
$loyaltyPoints[$asha] += 30;

foreach ($loyaltyPoints as $customer) {
    echo "{$customer->name}: {$loyaltyPoints[$customer]} points\n";
}

var_dump($loyaltyPoints->contains(new Customer('Asha')));

 

Output

Asha: 150 points
Bala: 45 points
bool(false)

 

  • Objects are identified by identity: a different object with the same name is not contained.
  • Iterating yields the objects; the attached data is read with $storage[$object].

WeakMap (PHP 8.0+) is a related class: it also maps objects to data, but does not keep the objects alive — when an object is no longer used elsewhere, its entry disappears automatically. It is ideal for caches attached to objects.


Arrays or SPL?

Use Arrays WhenUse SPL Structures When
The data is small or medium-sizedLarge queues where array_shift() would be slow
You need array functions (array_map, array_filter, sorting)You need priority ordering or a heap
Keys are strings or mixedKeys are objects (SplObjectStorage, WeakMap)
The data is passed to JSON, templates, or databasesThe structure's behavior (LIFO, FIFO) should be explicit in the code

 

For most everyday code, arrays remain the simplest choice. Reach for SPL when a structure's specific behavior or performance matters.


Common Mistakes

Popping or Extracting From Empty Structures

Effect: RuntimeException.

Fix: Check isEmpty() or count() first.

Relying on Order for Equal Priorities

Effect: Items with the same priority come out in an unexpected order.

Fix: Add a tie-breaker to the priority.

Using array_shift() for Large Queues

Effect: Each call re-indexes the array, making processing slow.

Fix: Use SplQueue.

Expecting SplObjectStorage to Compare by Value

Effect: Equal-looking objects are treated as different keys.

Fix: Use the same instance, or key by an identifier in a regular array.


Best Practices

  • Use SplStack and SplQueue to express LIFO and FIFO behavior clearly.
  • Use SplPriorityQueue and heaps for "most important / smallest first" processing.
  • Use SplObjectStorage or WeakMap when objects must act as keys.
  • Use SplFixedArray for large, fixed-size numeric datasets.
  • Default to arrays for ordinary data and switch to SPL when behavior or performance requires it.

Official reference: https\://www.php.net/manual/en/spl.datastructures.php

0 Comments

Reviewed before they appear

No comments yet.

PHP
PHP Home PHP Switch PHP Match Alternative Syntax PHP Loops While Loop Do While Loop For Loop Foreach Loop Nested Loops Break Statement PHP Intro PHP Install PHP Built-in Web Server PHP Syntax PHP Tags PHP and HTML PHP Comments PHP Multiline Comments PHP Variables Variables Scope PHP Casting Logical Operators Null Coalescing Operator Spaceship Operator Operator Precedence Continue Statement Modify Strings PHP If...Else...Elseif PHP If Modify Strings PHP If Operators PHP Functions Concatenate Strings PHP If...Else User-defined Functions Slicing Strings PHP Shorthand if Escape Characters Default Argument Values PHP Nested if Pass by Reference String Interpolation Named Arguments PHP File Upload Variadic Functions Return Values Search in Strings Multibyte Strings Type Declarations in Functions PHP Numbers PHP Math PHP Floats PHP Random Numbers PHP Constants PHP Properties PHP Methods PHP Constructor Constructor Property Promotion PHP Cookies PHP Destructor PHP Access Modifiers Readonly Properties PHP Sessions PHP Inheritance Method Overriding PHP Filters The final Keyword CSRF Protection PHP Filters Advanced Session Security Secure Cookies PHP Magic Constants File Upload Security PHP Callback Functions PHP Operators Filesystem Security PHP JSON Arithmetic Operators Error Reporting in Production Hiding PHP Assignment Operators PHP Configuration (php.ini) Comparison Operators PHP Command Line (CLI) PHP Exceptions Increment / Decrement Operators Migrating to PHP 8 PHP Form Validation PHP Form Required PHP Form URL/E-mail Error Handling Form Input Sanitizing Escaping Output (htmlspecialchars) Custom Error Handler Checkbox, Radio and Select Inputs Sticky Forms PHP Form Complete PHP Date and Time Date Formatting Error Logging HTTP Headers and Redirects Output Buffering Sending Email PHP cURL Consuming REST APIs PHP Generators AJAX PHP AJAX Database AJAX XML AJAX Live Search AJAX Poll AJAX with JSON Security Introduction Password Hashing SQL Injection Prevention XSS Prevention Garbage Collection Project: Simple Blog PHP What is OOP PHP Classes/Objects The $this Keyword Access Array Items Update Array Items Add Array Items Remove Array Items Sorting Arrays Multidimensional Arrays Array Destructuring Array Spread Operator Search in Arrays Merge Arrays PHP Abstract Classes PHP Interfaces Polymorphism PHP Traits PHP Static Methods PHP Static Properties Late Static Binding Magic Methods Object Cloning MySQL Database MySQL Connect MySQL Create DB MySQL Create Table MySQL Insert Data MySQL Get Last ID MySQL Insert Multiple MySQL Prepared MySQL Select Data MySQL Where Debugging PHP Project: Image Upload Gallery $_SESSION $_ENV PHP RegEx RegEx Patterns Heredoc and Nowdoc RegEx Modifiers preg_match preg_replace preg_split PHP RegEx Functions Nullable Types Mixed and Never Types Nullsafe Operator PHP Attributes PHP Fibers Readonly Classes Property Hooks (PHP 8.4) Asymmetric Visibility (PHP 8.4) Reflection API SPL Data Structures Composer
Ask about this post
AI Ask about this post

Ask questions about SPL Data Structures and get answers drawn from it.

Signed-in readers only.