In PHP, an array can be a list, a map, a record or a set, so an array type tells you almost nothing about what's inside it or whether it will change. This RFC from MichaΕ‚ Marcin Brzuchalski adds three new built-in types, vec, set and tuple. Each one has a declared element type, and none of them can be modified after you create it.

How it works

$ids   = vec[int]{1, 2, 3};
$perms = set[string]{"read", "write", "read"};   // {"read", "write"}
$pair  = tuple[int, string]{200, "OK"};
  • vec[T] is an ordered list, indexed from 0.
  • set[T] holds each value once and drops duplicates.
  • tuple[A, B] is a fixed-length record with a type for each position.

These are values, not objects and not arrays. PHP checks every element when you build one, and it doesn't coerce types, even without strict_types:

vec[int]{1, "2"};  // TypeError: Element 1 of vec[int] must be of type int, string given

You can use them as types for parameters, return values and properties:

function sum(vec[int] $values): int { /* … */ }

Reading and "changing" them

You can read a vec or tuple by position, loop over any of them with foreach, and check ->count and ->isEmpty. You can't write to them, so methods return a new copy instead:

$v = vec[int]{1, 2, 3};
$v->append(4);        // vec[int]{1,2,3,4}   ($v unchanged)
$v->withoutAt(0);     // vec[int]{2,3}

$s = set[int]{1, 2, 3};
$s->union(set[int]{3, 4, 5});     // {1,2,3,4,5}

A few other rules apply:

  • === compares contents, and a set ignores order.
  • ==, < and <=> throw a TypeError.
  • A collection is always truthy, even when it's empty.
  • There's no automatic conversion to or from array.
  • You can't use them in constant expressions yet.

The RFC says this has to live in the engine because PHP has no generics. It leaves map, shape, and methods like map and filter for later RFCs.

What it means for existing code

The words vec, set and tuple aren't reserved, so you can still have functions, classes and constants with those names. The one break is a constant named vec, set or tuple followed directly by [, like vec[0]. Writing vec [0] or (vec)[0] still works. The author found no such code in a scan and plans a wider check before a vote.

Where it stands

The RFC is a draft, version 1.0, dated August 4, 2026. It targets PHP 9.0, since PHP 8.6 is already in feature freeze. The implementation lives on the author's php-src fork, with a pull request to follow, and it will need a two-thirds majority to pass.