The Traversable Interface

The Traversable interface is the base interface that all classes can implement to be used in a foreach loop. It is not meant to be implemented directly; instead, it is extended by the Iterator and IteratorAggregate interfaces.

class MyCollection implements Iterator
{
    private array $items = [];
    private int $position = 0;

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

    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]);
    }
}

$collection = new MyCollection(["PHP", "Python", "Go"]);
foreach ($collection as $item) {
    echo $item;
}

// PHP Python Go

The Iterator Interface

The Iterator interface extends Traversable. It provides methods for iteration: current(), key(), next(), rewind(), and valid().


The IteratorAggregate Interface

Instead of implementing the Iterator interface directly, a class can implement IteratorAggregate and return an external iterator.

class MyAggregate implements IteratorAggregate
{
    private array $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }

    public function getIterator(): Traversable
    {
        return new ArrayIterator($this->data);
    }
}

$agg = new MyAggregate([1, 2, 3]);
foreach ($agg as $num) {
    echo $num;
}

// 123

The Throwable Interface

The Throwable interface is the base for all exceptions and errors in PHP. Both Exception and Error implement it.

try {
    throw new Exception("Something went wrong!");
} catch (Throwable $t) {
    echo "Caught throwable: " . $t->getMessage();
}

// Caught throwable: Something went wrong!

The Countable Interface

Classes implementing Countable must define the count() method. This makes them usable with PHP's count() function.

class Cart implements Countable
{
    private array $items = [];

    public function addItem($item)
    {
        $this->items[] = $item;
    }

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

$cart = new Cart();
$cart->addItem("Book");
$cart->addItem("Pen");

echo count($cart); // 2

The ArrayAccess Interface

This interface lets objects be accessed like arrays by implementing offsetGet, offsetSet, offsetExists, and offsetUnset.

class Container implements ArrayAccess
{
    private array $storage = [];

    public function offsetSet($key, $value): void
    {
        $this->storage[$key] = $value;
    }

    public function offsetGet($key): mixed
    {
        return $this->storage[$key] ?? null;
    }

    public function offsetExists($key): bool
    {
        return isset($this->storage[$key]);
    }

    public function offsetUnset($key): void
    {
        unset($this->storage[$key]);
    }
}

$c = new Container();
$c["foo"] = "bar";
echo $c["foo"]; // bar

The Serializable Interface

This interface provides custom serialization via serialize() and unserialize() methods.

class User implements Serializable
{
    private string $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

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

    public function unserialize($data): void
    {
        $this->name = unserialize($data);
    }
}

$user = new User("Orkhan");
$serialized = serialize($user);
echo $serialized;
// C:4:"User":13:{s:6:"Orkhan";}

$restored = unserialize($serialized);
var_dump($restored);
/*
object(User)#2 (1) {
  ["name":"User":private]=>
  string(6) "Orkhan"
}
*/

The Stringable Interface

Introduced in PHP 8.0, it is automatically implemented by any class with a __toString() method.

class Product implements Stringable
{
    private string $name;

    public function __construct($name)
    {
        $this->name = $name;
    }

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

$p = new Product("Laptop");
echo $p; // Product: Laptop

The UnitEnum Interface

The UnitEnum interface is automatically applied to all enumerations by the engine. It may not be implemented by user-defined classes. Enumerations may not override its methods, as default implementations are provided by the engine. It is available only for type checks.


The BackedEnum Interface

The BackedEnum interface is automatically applied to backed enumerations by the engine. It may not be implemented by user-defined classes. Enumerations may not override its methods, as default implementations are provided by the engine. It is available only for type checks.


The InternalIterator Class

Class to ease implementing IteratorAggregate for internal classes.


The Closure Class

Anonymous functions are instances of Closure.

$greet = function ($name) {
    return "Hello, $name!";
};

echo $greet("Orkhan"); // Hello, Orkhan!

The stdClass Class

A generic empty class that can be used for dynamic objects.

$obj = new stdClass();
$obj->name = "Orkhan";
$obj->role = "Developer";

var_dump($obj);

/*
object(stdClass)#1 (2) {
  ["name"]=>
  string(6) "Orkhan"
  ["role"]=>
  string(9) "Developer"
}
*/

The Generator Class

Created when using yield inside a function.

function numbers(): Generator {
    for ($i = 1; $i <= 3; $i++) {
        yield $i;
    }
}

foreach (numbers() as $n) {
    echo $n;
}

// 1 2 3

The Fiber Class

Introduced in PHP 8.1, fibers enable cooperative multitasking.

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend("Paused");
    echo "Resumed with: $value";
});

echo $fiber->start(); // Paused
$fiber->resume("Go on!"); // Resumed with: Go on!

The WeakReference Class

Allows holding a reference to an object without preventing its destruction.

$obj = new stdClass();
$weak = WeakReference::create($obj);

echo $weak->get() ? "Object exists" : "Destroyed";
// Object exists
unset($obj);
echo $weak->get() ? "Object exists" : "Destroyed";
// Destroyed

The WeakMap Class

Stores objects as keys without preventing garbage collection.

$map = new WeakMap();
$o = new stdClass();

$map[$o] = "Hello";
echo $map[$o]; // Hello

unset($o);
// $map is now empty automatically

The SensitiveParameterValue Class

Introduced in PHP 8.2 for hiding sensitive values in stack traces.

function login($username, SensitiveParameterValue $password) {
    throw new Exception("Debugging");
}

try {
    login("Orkhan", new SensitiveParameterValue("superSecret"));
} catch (Throwable $e) {
    var_dump($e->getTrace());
}

The __PHP_Incomplete_Class

This special class is used internally when unserialize() cannot fully restore a class because its definition is missing.

$data = 'O:8:"Unknown":0:{}'; 
$object = unserialize($data);

var_dump($object instanceof __PHP_Incomplete_Class); // true

Source: Orkhan Alishov's notes