> I would like to propose native type declarations for PHP array keys and > values. The RFC draft is available at:
https://wiki.php.net/rfc/typed_array_declarations Hello, Thanks for the RFC. I am also a long time silent follower of the list. I would like to highlight a possible mistake. I copy the text here: For by-value boundaries, one parameterized array is a subtype of another > when both its key and value types are subtypes: > array<K1, V1> <: array<K2, V2> > when K1 <: K2 and V1 <: V2 There are some problems here: 1. You have limited K to int or string, but none of these types can be subtyped. As a result K1<:K2 never applies. We can only have K1:=K2. 2. You also claim that V is covariant. However, this holds true only for read-only arrays. Write operations of an array use V in contra-variant positions. I am afraid that we cannot have sound covariant subtyping of an array, unless we clearly separate the read interface from the write one. Lazare INEPOLOGLOU Architecte Logiciel On Thu, 16 Jul 2026 at 11:27, Wendell Adriel <[email protected]> wrote: > Hi everyone, > > I've been off for quite a while from internals, so I'm going to > re-introduce myself briefly. > > I'm Wendell Adriel, I've been working with PHP since 2009. > Worked over a decade with PHP enterprise applications, and currently I'm > working as a Senior Software Engineer in the Laravel OSS Team. You can > check more about me on my website (link in my email signature). > > I would like to propose native type declarations for PHP array keys and > values. The RFC draft is available at: > > https://wiki.php.net/rfc/typed_array_declarations > > The proposal adds `array<TValue>` for integer-keyed arrays and > `array<TKey, TValue>` when the key type must be declared explicitly. Plain > `array` declarations remain unchanged. > > The RFC proposes three implementation levels that share the same syntax > and Reflection metadata, but they provide different runtime guarantees: > > ```php > final class ProductCatalog > { > public array<string, Product> $products = []; > } > > $catalog = new ProductCatalog(); > > $catalog->products = ['featured' => new stdClass()]; // Whole-property > assignment > $catalog->products['featured'] = new stdClass(); // Direct dimension > write > ``` > > - **Level 1** parses the declaration and exposes it through Reflection, > but does not validate elements. Both writes are accepted. > - **Level 2** validates keys and values when an array crosses a declared > boundary, such as a complete property assignment, argument, return value, > default, or typed class constant. The first write throws `TypeError`, but > the direct dimension write is still accepted. > - **Level 3** includes Level 2 and enforces the constraint for later > property mutations and references. Both writes throw `TypeError` before the > invalid value is stored. > > I currently recommend Level 3 for typed properties because it preserves > the guarantee the declaration appears to make. There is no implementation > yet, because I first wanted to see which implementation level would be > accepted. I will work on one after incorporating early feedback. > > I would appreciate any feedback, especially on the runtime semantics and > the appropriate implementation level. > > Thanks in advance! > > *---* > *Best Regards,* > *Wendell Adriel.* > *Software Engineer & Architect* > *https://wendelladriel.com <https://wendelladriel.com>* >
