Wendell Adriel, ingeniero de software senior en el equipo de Laravel OSS, ha publicado un borrador de RFC titulado «Typed array declarations» en la lista de correo de PHP Internals. La propuesta está disponible en https://wiki.php.net/rfc/typed_array_declarations y se discutió en un hilo iniciado el 16 de julio de 2026.
La RFC permitiría a los desarrolladores declarar los tipos de los valores de un array y, opcionalmente, los de las claves. La sintaxis `array<TValue>` significaría un array con claves enteras, mientras que `array<TKey, TValue>` se usaría cuando el tipo de clave debe ser explícito. Las declaraciones actuales de `array` sin parámetros permanecerían sin cambios.
El borrador define tres niveles de implementación que comparten la misma sintaxis y metadatos de Reflection, pero difieren en la aplicación. El nivel 1 reconoce la declaración durante el análisis y la expone a través de Reflection, sin comprobar elementos individuales. El nivel 2 valida claves y valores cuando un array atraviesa un límite declarado, como una asignación completa de propiedad, argumento de función, valor de retorno, valor por defecto o constante de clase tipada; sin embargo, las escrituras directas por dimensión, por ejemplo `$obj->prop['x'] = ...`, seguirían aceptándose. El nivel 3 incluye el nivel 2 y también aplica la restricción en mutaciones posteriores de la propiedad y referencias, por lo que tanto la asignación completa de la propiedad como la escritura directa por dimensión lanzarían un `TypeError` antes de que se almacene el valor no válido. Adriel recomienda actualmente el nivel 3 para propiedades tipadas porque preserva la garantía que parece ofrecer la declaración. Aún no existe una implementación; pidió comentarios sobre la semántica de tiempo de ejecución y el nivel adecuado antes de empezar a programar.
Lazare Inepologlou respondió primero. Señaló que, como la RFC limita las claves a `int` o `string`, ninguno puede tener subtipos, por lo que una relación de subtipado `K1 <: K2` nunca puede aplicarse y solo es posible `K1 = K2`. También argumentó que la covarianza de valores solo es segura para arrays de solo lectura; las operaciones de escritura colocan el tipo de valor en una posición contravariante, por lo que un subtipado covariante sólido requeriría separar claramente las interfaces de lectura y escritura. Adriel publicó una v0.2 de la RFC que incorpora esa retroalimentación.
Rob Landers planteó después preocupaciones más amplias. Considera que la propuesta se superpone significativamente con la RFC de genéricos reificados, que actualmente está en espera hasta después de la congelación de código actual; se espera que la discusión no se reanude hasta finales de agosto o principios de septiembre como muy pronto. Ambas propuestas deben responder las mismas preguntas sobre tipos parametrizados, varianza, Reflection, aplicación en tiempo de ejecución, inferencia e identidad de tipo, por lo que advirtió contra comprometer a PHP con reglas específicas de arrays antes de discutir el diseño más amplio de genéricos. De lo contrario, el lenguaje podría restringir los genéricos o terminar con dos modelos de parametrización incompatibles.
Landers también criticó el modelo de varianza propuesto. Para una colección nativa mutable, la varianza normalmente no es segura a menos que la API separe claramente la lectura de la escritura. La RFC de genéricos reificados hace que los parámetros genéricos sean invariantes por defecto y permite covarianza o contravarianza solo donde se pueda demostrar que son seguras. El borrador de arrays tipados, en cambio, trata `array<Dog>` como compatible con `array<Animal>` solo en ciertos límites por valor, apoyándose en la separación copy-on-write de PHP, y luego vuelve a ser invariante para alias modificables y añade reglas adicionales para referencias compartidas. Landers argumentó que esto no es una relación de subtipado normal, sino una compatibilidad de límite dependiente del contexto que depende del comportamiento interno de arrays y referencias del motor, lo cual sería difícil de entender para los usuarios y difícil de aplicar consistentemente por el motor. Sugirió hacer los arrays parametrizados invariantes, es decir, `array<int, Dog>` no sería un subtipo de `array<int, Animal>`, y ofrecer covarianza a través de una colección o interfaz de solo lectura si se desea.
Landers también consideró confusa la sintaxis de un argumento `array<TValue>`, porque implica implícitamente `array<int, TValue>`. No es un array general de valores porque se rechazan claves de tipo string, pero tampoco es una lista verdadera porque las claves enteras no necesitan ser contiguas ni empezar en cero. Esperaría que `array<TValue>` solo restringiera el tipo de valor dejando el tipo de clave como `int|string`, y sugirió un futuro `list<TValue>` para la forma más restrictiva con claves numéricas.
Una última preocupación fue la validación repetida en tiempo de ejecución. Como los arrays normales de PHP no conservan una identidad de tipo de elemento confiable, cualquier garantía de tipo se pierde cuando un array atraviesa un límite no tipado. En cada límite tipado posterior, PHP debe volver a validar todo el array recursivamente. Para arrays grandes o anidados, esto puede introducir un costo O(n) o recursivo O(n) en cada llamada. Landers prefirió firmemente esperar a la RFC de genéricos o, como mínimo, limitar esta RFC a experimentación de sintaxis y Reflection sin comprometerse con semántica independiente de varianza y tiempo de ejecución.
Adriel respondió que compartía estas preocupaciones. Dijo que ahora hay dos caminos posibles: implementar solo el nivel 1 en esta RFC, lo cual sería lo suficientemente simple para PHP 8.7, y posponer los niveles 2 y 3 a una RFC posterior después del diseño de genéricos; o aplazar toda la RFC hasta después de los genéricos y luego apuntar al nivel 2 o 3, siendo el nivel 3 su resultado preferido. Indicó que ha publicado una v0.2 y que estaría conforme con cualquiera de los dos enfoques.