Data Structures in PHP

12 essential data structures for PHP developers. Each one explained with Big O complexity, animated visuals, and real code samples you can copy.

Array

SplFixedArray / array

Fixed-size, contiguous block of memory. Elements are stored sequentially and accessed by index in constant time. The foundation of most other data structures.

7
3
9
1
5
[0]
[1]
[2]
[3]
[4]

arr[0] = 7

Complexity

Access by indexO(1)
SearchO(n)
Insert / DeleteO(n)

When to use

  • +You know the exact size at creation time
  • +You need the fastest possible index-based access
  • +Working with fixed-length data like matrices or buffers
PHP
// PHP arrays are dynamic, SplFixedArray is fixed-size
$fixed = new SplFixedArray(5);
$fixed[0] = 10;                     // O(1) - direct index
$fixed[1] = 20;
$fixed[2] = 30;
$val = $fixed[2];                   // O(1) -> 30

// Resize is expensive - allocates new internal storage
$fixed->setSize(10);                // O(n)

// Regular fixed-size simulation
$nums = [10, 20, 30, 40, 50];
$nums[0] = 99;                     // O(1)
sort($nums);                        // O(n log n)
$idx = array_search(30, $nums);    // O(n)

Dynamic Array

array

Resizable array that automatically grows when capacity is exceeded. The most commonly used data structure in most languages. Doubles its internal storage when full, giving amortized O(1) appends.

7
3
9
1
5
[0]
[1]
[2]
[3]
[4]

arr[0] = 7

Complexity

Access by indexO(1)
SearchO(n)
AppendO(1)*
Insert / Remove (middle)O(n)

When to use

  • +You need a resizable collection (most common case)
  • +You frequently access elements by index
  • +You mostly add or remove at the end
PHP
$names = ["Alice", "Bob", "Charlie"];

$names[] = "Diana";                       // O(1) amortized - append
array_splice($names, 1, 0, ["Eve"]);     // O(n) - insert at index
array_pop($names);                        // O(1) - remove last
array_shift($names);                      // O(n) - remove first

$has = in_array("Bob", $names);           // O(n)
$idx = array_search("Bob", $names);       // O(n)

sort($names);                              // O(n log n)
$squares = array_map(fn($x) => $x * $x, range(0, 9));  // O(n)

Stack

array (push/pop)

Last-In-First-Out (LIFO) collection. Only the top element is accessible. Used for tracking state that must be unwound in reverse order.

arrow_downward top
10

Push 10

Complexity

PushO(1)
PopO(1)
PeekO(1)
SearchO(n)

When to use

  • +Undo/redo functionality
  • +Expression parsing and evaluation
  • +DFS traversal of trees and graphs
  • +Matching brackets, parentheses validation
PHP
// Use array as stack
$stack = [];

array_push($stack, 10);     // O(1)
array_push($stack, 20);
array_push($stack, 30);

$top = end($stack);          // O(1) - peek -> 30
$val = array_pop($stack);   // O(1) - pop -> 30

// Interview pattern: valid parentheses
function isValid(string $s): bool {
    $pairs = ["(" => ")", "[" => "]", "{" => "}"];
    $st = [];
    foreach (str_split($s) as $c) {
        if (isset($pairs[$c])) $st[] = $pairs[$c];
        elseif (empty($st) || array_pop($st) !== $c) return false;
    }
    return empty($st);
}

Queue

SplQueue

First-In-First-Out (FIFO) collection. Elements are added at the back and removed from the front. Fundamental for breadth-first processing.

front
10
back

Enqueue 10

Complexity

EnqueueO(1)
DequeueO(1)
PeekO(1)
SearchO(n)

When to use

  • +BFS traversal of trees and graphs
  • +Task scheduling and job queues
  • +Message passing between components
  • +Rate limiting, buffering
PHP
$queue = new SplQueue();

$queue->enqueue("Task A");     // O(1)
$queue->enqueue("Task B");
$queue->enqueue("Task C");

$first = $queue->bottom();     // O(1) - peek front
$val = $queue->dequeue();      // O(1) - dequeue -> "Task A"
$empty = $queue->isEmpty();    // check

// Interview pattern: BFS
function bfs(?TreeNode $root): void {
    if (!$root) return;
    $q = new SplQueue();
    $q->enqueue($root);
    while (!$q->isEmpty()) {
        $node = $q->dequeue();
        echo $node->val . " ";
        if ($node->left)  $q->enqueue($node->left);
        if ($node->right) $q->enqueue($node->right);
    }
}

Hash Map

array (associative)

Maps keys to values using a hash function for near-constant-time lookups. The single most important data structure for coding interviews. Every language has a built-in implementation.

0
age:30
1
2
name:Al
3
city:NY

hash("age") = 0

Complexity

InsertO(1)*
LookupO(1)
DeleteO(1)
Contains keyO(1)

When to use

  • +Two Sum and frequency counting patterns
  • +Caching computed results (memoization)
  • +Grouping data by a key
  • +Any problem requiring O(1) lookup by key
PHP
$prices = ["apple" => 3, "banana" => 5];

$prices["cherry"] = 2;                    // O(1) - add
$prices["apple"] = 10;                    // O(1) - update
$has = array_key_exists("banana", $prices); // O(1)
unset($prices["cherry"]);                 // O(1)

$count = $prices["mango"] ?? 0;           // O(1) - null coalescing

// Interview pattern: Two Sum
function twoSum(array $nums, int $target): array {
    $seen = [];
    foreach ($nums as $i => $num) {
        $need = $target - $num;
        if (isset($seen[$need])) return [$seen[$need], $i]; // O(1)
        $seen[$num] = $i;                                    // O(1)
    }
    return [];
}

Hash Set

array_flip (keys as set)

Unordered collection of unique elements. Uses hashing internally for O(1) membership testing. Supports mathematical set operations like union, intersection, and difference.

0
age:30
1
2
name:Al
3
city:NY

hash("age") = 0

Complexity

AddO(1)*
ContainsO(1)
RemoveO(1)
Union / IntersectO(n)

When to use

  • +Checking if an element exists in O(1)
  • +Removing duplicates from a collection
  • +Set operations: union, intersection, difference
  • +Visited tracking in graph traversal
PHP
// PHP has no native Set - simulate with array keys
$s = array_flip([1, 2, 3, 4, 5]);   // values become keys

$s[6] = true;                // O(1) - add
unset($s[1]);                // O(1) - remove
$has = isset($s[4]);         // O(1) -> true

// Set operations using array functions
$other = array_flip([4, 5, 6, 7]);
$inter = array_intersect_key($s, $other);   // intersection
$union = $s + $other;                        // union
$diff  = array_diff_key($s, $other);        // difference

// Interview pattern: contains duplicate
function containsDuplicate(array $nums): bool {
    return count($nums) !== count(array_unique($nums));
}

Linked List

SplDoublyLinkedList

Sequence of nodes where each node points to the next (singly linked) or both next and previous (doubly linked). Efficient insertion and deletion at any known position, but no index-based access.

5
12
8
20

traversing: 5

Complexity

Insert at head/tailO(1)
Remove (given node)O(1)
SearchO(n)
Access by indexO(n)

When to use

  • +Frequent insertion/deletion in the middle
  • +Implementing LRU cache (with a hash map)
  • +When you need a deque (double-ended queue)
  • +Problems involving pointer manipulation
PHP
$list = new SplDoublyLinkedList();

$list->push(10);              // O(1) - add to tail
$list->push(20);
$list->unshift(5);            // O(1) - add to head

$list->add(1, 15);            // O(n) - insert at index
$first = $list->bottom();     // O(1) - peek head -> 5
$last  = $list->top();        // O(1) - peek tail -> 20

$list->pop();                 // O(1) - remove from tail
$list->shift();               // O(1) - remove from head

// Iterate
for ($list->rewind(); $list->valid(); $list->next()) {
    echo $list->current() . " ";   // 15 10
}

Sorted Set (BST)

sorted array

Collection of unique elements maintained in sorted order, typically backed by a balanced binary search tree (red-black tree). Supports range queries and O(log n) min/max.

831215

search(8)

Complexity

AddO(log n)
ContainsO(log n)
RemoveO(log n)
Min / MaxO(log n)

When to use

  • +Maintaining a sorted collection of unique items
  • +Range queries (all elements between X and Y)
  • +Sliding window problems needing sorted order
  • +Leaderboards, ranking systems
PHP
// Manual sorted array - maintain order on insert
$sorted = [1, 3, 5, 8, 9];

// Binary search for insertion point - O(log n)
function sortedInsert(array &$arr, int $val): void {
    $lo = 0; $hi = count($arr);
    while ($lo < $hi) {
        $mid = intdiv($lo + $hi, 2);
        if ($arr[$mid] < $val) $lo = $mid + 1;
        else $hi = $mid;
    }
    array_splice($arr, $lo, 0, [$val]);    // O(n) shift
}

sortedInsert($sorted, 4);      // [1, 3, 4, 5, 8, 9]
$min = $sorted[0];             // O(1) -> 1
$max = end($sorted);           // O(1) -> 9

// Range query
$between = array_filter($sorted, fn($x) => $x >= 4 && $x <= 8);

Sorted Map (BST)

ksort array

Key-value pairs maintained in sorted key order, typically backed by a balanced BST. Enables ordered iteration and range lookups that hash maps cannot provide.

831215

search(8)

Complexity

InsertO(log n)
LookupO(log n)
RemoveO(log n)
Iterate (sorted)O(n)

When to use

  • +You need sorted key-value pairs
  • +Ordered iteration over entries
  • +Range lookups by key
  • +When insertion order or sorted order matters
PHP
$sd = ["banana" => 2, "apple" => 5, "cherry" => 1];

$sd["date"] = 3;                    // O(1) - add
$val = $sd["apple"];                // O(1) -> 5
unset($sd["cherry"]);               // O(1)

// Sort by keys - O(n log n)
ksort($sd);

// Iterate in sorted key order
foreach ($sd as $key => $value) {
    echo "$key: $value\n";
}
// apple: 5, banana: 2, date: 3

$keys = array_keys($sd);
$firstKey = $keys[0];              // "apple"
$lastKey  = end($keys);           // "date"

Priority Queue (Heap)

SplPriorityQueue

Collection where elements are dequeued by priority rather than insertion order. Typically implemented as a binary heap. Essential for shortest-path algorithms and top-K problems.

13579

min-heap

Complexity

InsertO(log n)
Extract min/maxO(log n)
PeekO(1)
SearchO(n)

When to use

  • +Dijkstra's shortest path algorithm
  • +Merge K sorted lists/streams
  • +Top-K / Kth largest element problems
  • +Event-driven simulation, scheduling
PHP
$pq = new SplPriorityQueue();

// Higher priority number = dequeued first (max-heap)
$pq->insert("low", 1);          // O(log n)
$pq->insert("high", 3);
$pq->insert("medium", 2);

$top = $pq->top();               // O(1) - peek -> "high"
$val = $pq->extract();           // O(log n) - extract -> "high"

// Min-heap: negate priorities
$minPq = new SplPriorityQueue();
$minPq->insert("C", -3);
$minPq->insert("A", -1);
$minPq->insert("B", -2);
$minPq->extract();               // O(log n) -> "A" (priority -1)

// Set extraction mode for key-priority pairs
$pq->setExtractFlags(SplPriorityQueue::EXTR_BOTH);

Concurrent Hash Map

flock + APCu

Thread-safe hash map designed for concurrent read/write access from multiple threads. Uses fine-grained locking or lock-free techniques instead of a single global lock.

0
age:30
1
2
name:Al
3
city:NY

hash("age") = 0

Complexity

InsertO(1)*
LookupO(1)
DeleteO(1)
Atomic updateO(1)*

When to use

  • +Multi-threaded caching
  • +Shared state across threads or async tasks
  • +Producer-consumer patterns with keyed data
  • +When you need concurrent reads and writes
PHP
// PHP is single-threaded per request; use mutex for shared state
// With parallel extension (PHP 8.2+)

// Simple file-based locking for shared cache
function atomicGet(string $key): mixed {
    $fp = fopen("/tmp/cache_$key.lock", "c+");
    flock($fp, LOCK_SH);                   // shared read lock
    $data = apcu_fetch($key);              // O(1) - APCu cache read
    flock($fp, LOCK_UN);
    fclose($fp);
    return $data;
}

function atomicSet(string $key, mixed $val): void {
    $fp = fopen("/tmp/cache_$key.lock", "c+");
    flock($fp, LOCK_EX);                   // exclusive write lock
    apcu_store($key, $val);                // O(1) - APCu cache write
    flock($fp, LOCK_UN);
    fclose($fp);
}

Memory View / Slice

substr / array_slice

Zero-copy view over a contiguous region of memory. Lets you reference a portion of an array or buffer without allocating new memory. Critical for performance-sensitive parsing and processing.

1
2
3
4
5
6

Span[0..3] = [1, 2, 3]

Complexity

Create sliceO(1)
Access by indexO(1)
SearchO(n)
CopyO(n)

When to use

  • +Parsing strings or binary data without copies
  • +Processing sub-arrays without allocation
  • +High-performance, zero-allocation code paths
  • +Interop with native or unmanaged memory
PHP
// substr - string slicing (returns copy)
$data = "Hello, World!";
$chunk = substr($data, 7, 5);          // O(k) -> "World"

// array_slice - array slicing (returns copy)
$nums = [10, 20, 30, 40, 50];
$slice = array_slice($nums, 1, 3);     // O(k) -> [20, 30, 40]

// pack/unpack for binary data views
$bin = pack("N2", 42, 100);            // pack two 32-bit ints
$vals = unpack("N2val", $bin);         // O(1) -> [val1 => 42, val2 => 100]

// SplFixedArray for contiguous memory
$buf = SplFixedArray::fromArray([1, 2, 3, 4, 5]);
$buf[0] = 99;                          // O(1) - direct access
// No true zero-copy view in PHP - slicing always copies

Big O Comparison

Average-case time complexity. * = amortized.

StructureAccessSearchInsertDelete
ArrayO(1)O(n)O(n)O(n)
Dynamic ArrayO(1)O(n)O(1)*O(n)
StackO(n)O(n)O(1)*O(1)
QueueO(n)O(n)O(1)*O(1)
Hash MapO(1)O(1)O(1)*O(1)
Hash SetN/AO(1)O(1)*O(1)
Linked ListO(n)O(n)O(1)O(1)
Sorted SetO(n)O(log n)O(log n)O(log n)
Sorted MapO(log n)O(log n)O(log n)O(log n)
Priority QueueO(n)O(n)O(log n)O(log n)
Concurrent MapO(1)O(1)O(1)*O(1)
Memory ViewO(1)O(n)N/AN/A

Which collection should I use?

I need to...Use
Store items by index, resize dynamicallyList / Dynamic Array
Map keys to values with O(1) lookupHashMap / Dictionary
Track unique items, check existence in O(1)HashSet / Set
Last-in-first-out (undo, DFS, brackets)Stack
First-in-first-out (BFS, task queues)Queue
Keep elements sorted at all timesSortedSet / TreeSet
Process items by priority (Dijkstra, top-K)PriorityQueue / Heap
Insert/delete at a known position in O(1)LinkedList
Sorted key-value pairsSortedDictionary / TreeMap
Thread-safe shared cacheConcurrentDictionary
Slice arrays/strings without copyingSpan / Slice / memoryview

Frequently Asked Questions

What are the most important data structures in PHP?add

The most commonly used are dynamic arrays (List/ArrayList/vector), hash maps (Dictionary/HashMap/dict), and hash sets. For interviews, also know stacks, queues, trees, and priority queues. These cover 90%+ of coding interview problems.

Which PHP data structure should I learn first?add

Start with the dynamic array and hash map. Together they solve the majority of interview problems. Then learn stacks (for DFS, bracket matching) and queues (for BFS). After that, tackle trees, heaps, and graphs.

Does Big O complexity change between languages?add

No. Big O measures algorithmic complexity, not language-specific performance. A hash map lookup is O(1) whether you use Python dict, Java HashMap, or C# Dictionary. Constant factors differ (C++ is faster than Python in wall-clock time), but Big O is the same.

Is there a built-in priority queue in PHP?add

It depends on the language runtime. Check the PHP standard library documentation for heap or priority queue support.

Know the structures.
Now use them under pressure.

Practice with an AI interviewer that asks you to implement, optimize, and explain data structure choices in real time.

Try a free mock interviewarrow_forward