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:
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 throwsTypeError, 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 throwTypeErrorbefore 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
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:
- 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. - 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 wendelladriel.ti@gmail.com
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
arraydeclarations remain unchanged.The RFC proposes three implementation levels that share the same syntax
and Reflection metadata, but they provide different runtime guarantees: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 throwsTypeError, 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 throwTypeErrorbefore 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