La Standard PHP Library (SPL) incluye estructuras de datos listas para usar que evitan los errores silenciosos de utilizar arrays genéricos para todo. SplStack y SplQueue son las dos más habituales: la primera implementa una pila LIFO (Last In, First Out) y la segunda una cola FIFO (First In, First Out). Ambas extienden SplDoublyLinkedList y lanzan excepciones cuando se intenta leer de una estructura vacía.
SplStack: pila LIFO
Una pila almacena elementos y los devuelve en orden inverso al de inserción. Es el comportamiento natural del historial de navegación, de las operaciones de deshacer o de la pila de llamadas en un depurador.
<?php
$pila = new SplStack();
// push() añade al tope de la pila
$pila->push('acción 1');
$pila->push('acción 2');
$pila->push('acción 3');
echo $pila->top(); // 'acción 3' (sin extraer)
echo $pila->count(); // 3
// pop() extrae del tope (LIFO)
echo $pila->pop(); // 'acción 3'
echo $pila->pop(); // 'acción 2'
echo $pila->pop(); // 'acción 1'
// Excepción si se intenta pop() en pila vacía
try {
$pila->pop();
} catch (RuntimeException $e) {
echo $e->getMessage(); // "Can't pop from an empty datastructure"
}
?>
Historial de deshacer con SplStack
Un editor de texto sencillo puede usar SplStack para implementar undo: cada acción se guarda en la pila y deshacer significa extraer la última acción guardada.
<?php
class EditorTexto
{
private string $texto = '';
private SplStack $historial;
public function __construct()
{
$this->historial = new SplStack();
}
public function escribir(string $fragmento): void
{
$this->historial->push($this->texto); // guardar estado anterior
$this->texto .= $fragmento;
}
public function deshacer(): void
{
if ($this->historial->isEmpty()) {
throw new RuntimeException('No hay acciones que deshacer.');
}
$this->texto = $this->historial->pop();
}
public function contenido(): string
{
return $this->texto;
}
}
$editor = new EditorTexto();
$editor->escribir('Hola ');
$editor->escribir('mundo');
echo $editor->contenido(); // "Hola mundo"
$editor->deshacer();
echo $editor->contenido(); // "Hola "
$editor->deshacer();
echo $editor->contenido(); // ""
?>
SplQueue: cola FIFO
Una cola entrega los elementos en el mismo orden en que fueron añadidos: el primero en entrar es el primero en salir. Es el modelo natural para colas de tareas, emails pendientes de enviar o peticiones a procesar.
<?php
$cola = new SplQueue();
// enqueue() añade al final de la cola
$cola->enqueue('[email protected]');
$cola->enqueue('[email protected]');
$cola->enqueue('[email protected]');
echo $cola->count(); // 3
// dequeue() extrae del frente (FIFO)
echo $cola->dequeue(); // '[email protected]'
echo $cola->dequeue(); // '[email protected]'
echo $cola->dequeue(); // '[email protected]'
// bottom() y top(): ver sin extraer
$cola->enqueue('a');
$cola->enqueue('b');
echo $cola->bottom(); // 'a' (el más antiguo)
echo $cola->top(); // 'b' (el más reciente)
?>
Cola de emails pendientes
<?php
class ColaEmails
{
private SplQueue $cola;
public function __construct()
{
$this->cola = new SplQueue();
// Modo IT_MODE_DELETE: los nodos se eliminan al iterar
$this->cola->setIteratorMode(SplQueue::IT_MODE_DELETE | SplQueue::IT_MODE_FIFO);
}
public function encolar(array $email): void
{
$this->cola->enqueue($email);
}
public function procesarLote(int $maximo = 10): int
{
$enviados = 0;
while (!$this->cola->isEmpty() && $enviados < $maximo) {
$email = $this->cola->dequeue();
$this->enviar($email);
$enviados++;
}
return $enviados;
}
private function enviar(array $email): void
{
// mail($email['destino'], $email['asunto'], $email['cuerpo']);
echo "Enviado a: {$email['destino']}n";
}
}
$cola = new ColaEmails();
$cola->encolar(['destino' => '[email protected]', 'asunto' => 'Bienvenida', 'cuerpo' => '...']);
$cola->encolar(['destino' => '[email protected]', 'asunto' => 'Recordatorio', 'cuerpo' => '...']);
$cola->procesarLote(5);
?>
La documentación oficial de SplDoublyLinkedList, de la que heredan SplStack y SplQueue, describe todos los modos de iteración disponibles, los métodos de acceso posicional y las diferencias de rendimiento frente a los arrays nativos de PHP.
