Introducción a los Generics en PHP: qué son y para qué sirven
Si estás empezando a aprender PHP o ya llevas un tiempo escribiendo en él, seguramente te has encontrado con situaciones en las que una función o clase debe trabajar con diferentes tipos de datos. Por ejemplo, creas una colección que puede almacenar números, cadenas y objetos. Sin Generics (tipos genéricos), tienes que escribir clases separadas para cada tipo o usar tipos mixtos (mixed), lo que reduce la seguridad del código.
Los Generics son un mecanismo que permite crear clases, interfaces y funciones que trabajan con diferentes tipos de datos, manteniendo un tipado estricto. En PHP, el soporte para Generics apareció a partir de la versión 8.0, y en PHP 8.1 y 8.2 se mejoró significativamente. En este artículo, analizaremos para qué sirven, cómo usarlos y qué ventajas ofrecen.
¿Para qué sirven los Generics en PHP?
El problema de la falta de tipos genéricos
Imagina que escribes una clase para trabajar con una lista de elementos. Sin Generics, tendrías que usar el tipo mixed o escribir clases separadas para cada tipo de dato:
<?php// Sin Generics — inseguroclass SimpleList { private array $items = [];
public function add($item): void { $this->items[] = $item; }
public function get(int $index): mixed { return $this->items[$index] ?? null; }}
// Uso$list = new SimpleList();$list->add(42);$list->add('cadena'); // No se generará error, pero la lógica se rompe$value = $list->get(0); // Tipo mixed — el IDE no sugerirá que es int?>Como ves, este enfoque provoca errores potenciales: puedes agregar accidentalmente una cadena donde solo se esperan números, y el IDE no podrá advertirte.
Ventajas de los Generics
- Seguridad de tipos: el compilador y el IDE verifican la compatibilidad de tipos al escribir el código.
- Reutilización: una misma clase o función funciona con cualquier tipo de dato.
- Legibilidad del código: queda claro de inmediato qué tipos se esperan.
- Menos errores: se eliminan las incoherencias accidentales de tipos.
Con Generics, la misma clase de lista se vuelve segura y universal:
<?php// Con Generics — seguroclass GenericList { private array $items = [];
public function add(T $item): void { $this->items[] = $item; }
public function get(int $index): ?T { return $this->items[$index] ?? null; }}
// Uso$intList = new GenericList();$intList->add(42);// $intList->add('cadena'); // ¡Error de tipo!
$stringList = new GenericList();$stringList->add('Hola');$value = $stringList->get(0); // El IDE sabe que es string?>Cómo usar Generics en PHP
Sintaxis básica
Los Generics en PHP se declaran con corchetes angulares <> y la letra T (de Type) — este es el nombre común para la variable de tipo. Puedes usar cualquier nombre, pero T es el estándar.
Ejemplo con una clase:
<?phpclass Container { private T $value;
public function __construct(T $value) { $this->value = $value; }
public function getValue(): T { return $this->value; }}
$intContainer = new Container(100);$stringContainer = new Container('Hola');?>Restricciones de tipos
A veces es necesario que el tipo del parámetro cumpla con una interfaz o clase específica. Para ello se usan restricciones (bounds):
<?phpinterface Printable { public function print(): string;}
class Document implements Printable { public function print(): string { return 'Documento'; }