Wendell Adriel, Senior Software Engineer im Laravel-OSS-Team, hat einen Entwurf für die RFC „Typed array declarations“ auf der PHP-Internals-Mailingliste veröffentlicht. Der Vorschlag liegt unter https://wiki.php.net/rfc/typed_array_declarations und wurde in einem Thread diskutiert, der am 16. Juli 2026 begann.
Die RFC würde Entwicklern erlauben, die Typen von Array-Werten und optional auch Schlüsseln zu deklarieren. Die Syntax `array<TValue>` soll ein Array mit Integer-Schlüsseln bedeuten, während `array<TKey, TValue>` zum Einsatz kommt, wenn der Schlüsseltyp explizit angegeben werden muss. Bestehende einfache `array`-Deklarationen blieben unverändert.
Der Entwurf definiert drei Implementierungsstufen, die dieselbe Syntax und Reflection-Metadaten nutzen, sich aber in der Durchsetzung unterscheiden. Stufe 1 erkennt die Deklaration beim Parsen an und stellt sie über Reflection bereit, prüft aber keine einzelnen Elemente. Stufe 2 validiert Schlüssel und Werte, wenn ein Array eine deklarierte Grenze überschreitet, beispielsweise bei vollständiger Property-Zuweisung, Funktionsargument, Rückgabewert, Standardwert oder typisierter Klassenkonstante; direkte Dimensionsschreibzugriffe wie `$obj->prop['x'] = ...` blieben jedoch erlaubt. Stufe 3 umfasst Stufe 2 und erzwingt die Typangabe auch bei späteren Property-Mutationen und Referenzen, sodass sowohl eine komplette Property-Zuweisung als auch ein direkter Dimensionsschreibzugriff einen `TypeError` auslösen, bevor der ungültige Wert gespeichert wird. Adriel empfiehlt derzeit Stufe 3 für typisierte Properties, weil sie die Garantie der Deklaration bewahrt. Eine Implementierung existiert noch nicht; er bat um Rückmeldungen zu den Laufzeitsemantiken und der passenden Stufe, bevor er mit der Programmierung beginnt.
Lazare Inepologlou antwortete als Erster. Er wies darauf hin, dass die RFC Schlüssel auf `int` oder `string` beschränkt; beide können nicht abgeleitet werden, daher kann eine Schlüssel-Subtyp-Relation `K1 <: K2` nie gelten und nur `K1 = K2` möglich ist. Außerdem argumentierte er, dass Wert-Kovarianz nur für schreibgeschützte Arrays sinnvoll ist; Schreiboperationen setzen den Werttyp in eine kontravariante Position, weshalb eine stimmige kovariante Subtypisierung eine klare Trennung von Lese- und Schreibinterface erfordern würde. Adriel veröffentlichte daraufhin eine v0.2 der RFC, die dieses Feedback aufgriff.
Danach äußerte Rob Landers grundsätzliche Bedenken. Seiner Ansicht nach überschneidet sich der Vorschlag erheblich mit der RFC für reifizierte Generics, die derzeit bis nach der laufenden Code-Freeze-Pause zurückgestellt ist; eine Diskussion ist frühestens Ende August oder Anfang September wieder zu erwarten. Beide Vorschläge müssen dieselben Fragen zu parametrisierten Typen, Varianz, Reflection, Laufzeitdurchsetzung, Inferenz und Typidentität beantworten, daher warnte er davor, PHP auf spezifische Array-Regeln festzulegen, bevor das umfassendere Generics-Design diskutiert wurde. Andernfalls könnte die Sprache entweder die Generics-Entwicklung einengen oder mit zwei unterschiedlichen Parametrisierungsmodellen enden.
Landers kritisierte auch das vorgeschlagene Varianzmodell. Für eine veränderliche eingebaute Collection ist Varianz normalerweise unsicher, es sei denn, die API trennt Lesen und Schreiben klar. Die RFC für reifizierte Generics macht generische Parameter daher standardmäßig invariant und erlaubt Kovarianz oder Kontravarianz nur, wo sie als sicher nachgewiesen werden kann. Der Entwurf für typisierte Arrays behandelt `array<Dog>` dagegen nur an ausgewählten By-Value-Grenzen als kompatibel mit `array<Animal>` und stützt sich dabei auf PHPs Copy-on-Write-Trennung; für beschreibbare Aliase wird es wieder invariant und erfordert zusätzliche Regeln für gemeinsame Referenzen. Landers argumentierte, dass dies keine normale Subtyp-Beziehung, sondern eine kontextabhängige Grenzkompatibilität ist, die vom internen Array-Verhalten und Referenzverhalten abhängt. Das wäre für Nutzer schwer zu verstehen und für die Engine schwer konsistent durchzusetzen. Er schlug vor, parametrisierte Arrays invariant zu machen, also `array<int, Dog>` nicht als Subtyp von `array<int, Animal>` zu betrachten, und Kovarianz gegebenenfalls über eine separate schreibgeschützte Collection oder ein Interface anzubieten.
Ebenfalls verwirrend fand Landers die Ein-Argument-Syntax `array<TValue>`, weil sie implizit `array<int, TValue>` bedeutet. Es ist kein allgemeines Array von Werten, da String-Schlüssel abgelehnt werden, aber auch keine echte Liste, weil die Integer-Schlüssel nicht zusammenhängend oder nullbasiert sein müssen. Seiner Erwartung nach sollte `array<TValue>` nur den Werttyp einschränken und den Schlüsseltyp bei `int|string` belassen; für die strengere numerisch-indizierte Form schlug er ein zukünftiges `list<TValue>` vor.
Ein letzter Punkt war die wiederholte Laufzeitprüfung. Da gewöhnliche PHP-Arrays keine vertrauenswürdige Elementtypidentität speichern, geht jede Typgarantie verloren, wenn ein Array eine untypierte Grenze passiert. An jeder folgenden typisierten Grenze muss PHP das gesamte Array erneut rekursiv prüfen. Bei großen oder verschachtelten Arrays entsteht dadurch an jedem Aufruf ein potenzieller O(n)- oder rekursiver O(n)-Aufwand. Landers plädierte deshalb dafür, auf die Generics-RFC zu warten oder zumindest diese RFC auf Syntax- und Reflection-Experimente zu beschränken, ohne eigene Varianz- und Laufzeitsemantik festzulegen.
Adriel antwortete, dass er die Bedenken teile. Er sieht nun zwei mögliche Wege: nur Stufe 1 in dieser RFC umzusetzen, was einfach genug für PHP 8.7 wäre, und Stufe 2 sowie 3 in eine spätere RFC nach dem Generics-Design zu verschieben; oder die gesamte RFC bis nach den Generics zurückzustellen und danach Stufe 2 oder 3 anzustreben, wobei er Stufe 3 bevorzugt. Er sagte, dass er inzwischen eine v0.2 veröffentlicht habe, und mit beiden Ansätzen leben könne.