Skip to content
Code Kata
Go back

PHP Core Concepts

Suggest edit

Table of contents

Open Table of contents

Overview

PHP has evolved from a templating language into a full-featured OOP language with a rich standard library. This reference covers the core concepts you’ll use across the kata exercises.

Object-Oriented Programming

Classes and Inheritance

abstract class Animal {
    public function __construct(
        protected string $name,
    ) {}

    abstract public function speak(): string;

    public function getName(): string {
        return $this->name;
    }
}

class Dog extends Animal {
    public function speak(): string {
        return "{$this->name} says: Woof!";
    }
}

Interfaces

Interfaces define contracts. A class can implement multiple interfaces:

interface Comparable {
    public function compareTo(mixed $other): int;
}

interface Stringable {
    public function __toString(): string;
}

class Temperature implements Comparable, Stringable {
    public function __construct(private float $degrees) {}

    public function compareTo(mixed $other): int {
        return $this->degrees <=> $other->degrees;
    }

    public function __toString(): string {
        return "{$this->degrees";
    }
}

Abstract Classes vs Interfaces

FeatureAbstract ClassInterface
MethodsCan have implementationsOnly signatures (+ default since PHP 8.0)
PropertiesYesNo (until property hooks)
ConstructorYesNo
MultipleSingle inheritanceMultiple implementation

Traits

Horizontal code reuse without inheritance:

trait Timestampable {
    private ?DateTimeImmutable $createdAt = null;
    private ?DateTimeImmutable $updatedAt = null;

    public function setCreatedAt(): void {
        $this->createdAt = new DateTimeImmutable();
    }

    public function getCreatedAt(): ?DateTimeImmutable {
        return $this->createdAt;
    }
}

class BlogPost {
    use Timestampable;

    public function __construct(public string $title) {
        $this->setCreatedAt();
    }
}

Conflict Resolution

class MyClass {
    use TraitA, TraitB {
        TraitA::method insteadof TraitB;
        TraitB::method as methodFromB;
    }
}

Closures and Callables

Closures

$multiplier = function (int $factor): Closure {
    return fn(int $n): int => $n * $factor;
};

$double = $multiplier(2);
echo $double(5); // 10

Arrow Functions

Short closures with implicit $this and variable capture:

$numbers = [1, 2, 3, 4, 5];
$squared = array_map(fn($n) => $n ** 2, $numbers);

First-Class Callables (PHP 8.1+)

$lengths = array_map(strlen(...), ['hello', 'world']);

Generators

Memory-efficient iteration for large datasets:

function fibonacci(): Generator {
    [$a, $b] = [0, 1];
    while (true) {
        yield $a;
        [$a, $b] = [$b, $a + $b];
    }
}

$fib = fibonacci();
for ($i = 0; $i < 10; $i++) {
    echo $fib->current() . ' ';
    $fib->next();
}
// 0 1 1 2 3 5 8 13 21 34

Delegated Generators

function inner(): Generator {
    yield 1;
    yield 2;
}

function outer(): Generator {
    yield 0;
    yield from inner();
    yield 3;
}

// 0, 1, 2, 3

SPL Data Structures

PHP’s Standard PHP Library provides built-in data structures:

SplStack and SplQueue

$stack = new SplStack();
$stack->push('a');
$stack->push('b');
echo $stack->pop(); // 'b' (LIFO)

$queue = new SplQueue();
$queue->enqueue('a');
$queue->enqueue('b');
echo $queue->dequeue(); // 'a' (FIFO)

SplPriorityQueue

$pq = new SplPriorityQueue();
$pq->insert('low', 1);
$pq->insert('high', 10);
$pq->insert('medium', 5);

echo $pq->extract(); // 'high'
echo $pq->extract(); // 'medium'

SplFixedArray

Fixed-size array with better memory usage:

$arr = new SplFixedArray(5);
$arr[0] = 'hello';
// $arr[10] = 'error'; // RuntimeException

SplDoublyLinkedList

$list = new SplDoublyLinkedList();
$list->push('a');
$list->push('b');
$list->unshift('z'); // prepend

foreach ($list as $item) {
    echo $item; // z, a, b
}

SplHeap

class MinHeap extends SplHeap {
    protected function compare(mixed $a, mixed $b): int {
        return $b <=> $a; // reverse for min-heap
    }
}

$heap = new MinHeap();
$heap->insert(5);
$heap->insert(1);
$heap->insert(3);
echo $heap->extract(); // 1

Arrays as Hash Maps

PHP arrays are ordered hash maps — one of the most versatile built-in data structures in any language:

$map = [];
$map['key1'] = 'value1';
$map['key2'] = 'value2';

// Check existence
isset($map['key1']); // true

// Iterate with keys
foreach ($map as $key => $value) {
    echo "$key: $value\n";
}

// Array functions as map operations
$keys = array_keys($map);
$values = array_values($map);
$filtered = array_filter($map, fn($v) => strlen($v) > 5);

Error Handling

Exceptions

class InsufficientFundsException extends RuntimeException {
    public function __construct(
        public readonly float $balance,
        public readonly float $amount,
    ) {
        parent::__construct(
            "Cannot withdraw {$amount}: balance is {$balance}"
        );
    }
}

try {
    withdraw(100.0);
} catch (InsufficientFundsException $e) {
    echo "Balance: {$e->balance}";
} catch (RuntimeException $e) {
    echo $e->getMessage();
} finally {
    closeConnection();
}

Exception Hierarchy

Throwable
├── Error (internal engine errors)
│   ├── TypeError
│   ├── ValueError
│   └── ...
└── Exception
    ├── RuntimeException
    ├── LogicException
    │   ├── InvalidArgumentException
    │   └── OutOfRangeException
    └── ...

Magic Methods

Key magic methods used in data structure implementations:

class Collection implements Countable, ArrayAccess, Iterator {
    private array $items = [];
    private int $position = 0;

    public function __construct(array $items = []) {
        $this->items = array_values($items);
    }

    // Countable
    public function count(): int {
        return count($this->items);
    }

    // ArrayAccess
    public function offsetExists(mixed $offset): bool {
        return isset($this->items[$offset]);
    }

    public function offsetGet(mixed $offset): mixed {
        return $this->items[$offset];
    }

    public function offsetSet(mixed $offset, mixed $value): void {
        if ($offset === null) {
            $this->items[] = $value;
        } else {
            $this->items[$offset] = $value;
        }
    }

    public function offsetUnset(mixed $offset): void {
        unset($this->items[$offset]);
        $this->items = array_values($this->items);
    }

    // Iterator
    public function current(): mixed { return $this->items[$this->position]; }
    public function key(): int { return $this->position; }
    public function next(): void { $this->position++; }
    public function rewind(): void { $this->position = 0; }
    public function valid(): bool { return isset($this->items[$this->position]); }
}

Key Takeaways

  1. Interfaces over inheritance — prefer composition and contracts
  2. SPL data structures — use them instead of reinventing wheels in production
  3. Generators — essential for memory-efficient iteration
  4. Arrays are hash maps — PHP’s most powerful built-in data structure
  5. Named arguments + enums + match — modern PHP is expressive and type-safe

Suggest edit
Share this post on:

Previous Post
Python 3.10+: Key Updates by Version
Next Post
PHP 8.x: Key Updates by Version