# What Are std Containers in TypePHP and Why Use Them Over PHP Arrays

> Discover TypePHP's std containers like std::vector and std::map. Gain compile-time type safety and up to 10x performance gains over PHP arrays by eliminating zval overhead. Learn why they are superior.

- Repository: [Swoole Project/typephp](https://github.com/swoole/typephp)
- Tags: deep-dive
- Published: 2026-08-30

---

**TypePHP provides strongly-typed C++ standard library containers (`std::array`, `std::vector`, `std::ordered_map`, and `std::map`) that deliver compile-time type safety and up to 10× performance improvements over native PHP arrays by eliminating zval overhead and hash table indirection.**

The swoole/typephp project extends PHP with Ahead-of-Time (AOT) compilation capabilities, introducing `std` containers that bridge PHP's dynamic syntax with C++'s static performance characteristics. Unlike native PHP arrays—which store generic `zval` structures and rely on dynamic hash tables—these containers allow the compiler to generate direct memory accesses based on declared types.

## Core std Container Types in TypePHP

TypePHP implements four primary container templates wrapped by a PHPX Box interface. Each container enforces type constraints at compile time, enabling the AOT compiler to emit optimized C++ code instead of generic `php::Array` operations.

| Container | Characteristics | When to use |
|---|---|---|
| `std::array(Type, length)` | Fixed‑length, compile‑time element type, bounds‑checked | Fixed‑size buffers, matrices, numeric tables |
| `std::vector(Type[, length])` | Dynamically‑sized, contiguous memory, fixed element type | Large homogeneous collections, hot‑loop iteration |
| `std::ordered_map(KeyType, ValueType)` | Ordered key‑value map, fixed key/value types | Stable ordering required, e.g., lookup tables |
| `std::map(KeyType, ValueType)` | Hash‑table map, fixed key/value types | High‑throughput lookups where ordering is irrelevant |

According to [`docs/en/STD_CONTAINERS.md`](https://github.com/swoole/typephp/blob/main/docs/en/STD_CONTAINERS.md), these containers are implemented as C++ templates (e.g., `php::StdVector<php::Int>`), allowing the compiler to know the exact element-type, key-type, and container shape during compilation.

## Performance Advantages Over Native PHP Arrays

### Compile-Time Type Knowledge

Because element and key types are declared explicitly in `std::vector(Type::Int)` or `std::map(Type::String, Type::Float)`, the compiler can emit direct C++ template instantiations. As documented in [`docs/en/STD_CONTAINERS.md`](https://github.com/swoole/typephp/blob/main/docs/en/STD_CONTAINERS.md), this eliminates the need for runtime type checking and generic `php::Var` operations that plague standard PHP arrays.

### Reduced Memory Overhead

PHP arrays store a `zval` per element, maintain dynamic hash tables, and perform reference-counting with copy-on-write semantics. Std containers store raw C++ scalars in contiguous memory blocks, eliminating type tags, hash lookups, and indirections. Benchmarks in [`README.md`](https://github.com/swoole/typephp/blob/main/README.md) (lines 77-88) demonstrate approximately **10× speedup** over equivalent PHP array operations.

### Improved Cache Locality

Containers like `std::vector` and `std::array` allocate contiguous memory, significantly improving CPU cache hit rates during tight loops. This is particularly critical for numerical computing and matrix operations where PHP arrays would trigger frequent cache misses due to pointer chasing.

### Early Error Detection

Type mismatches are caught at compile time rather than runtime. Attempting to insert a string into a `std::vector(Type::Int)` triggers a compilation error, preventing the subtle runtime exceptions common in dynamic PHP code.

## Practical Usage Examples

The following examples demonstrate how to declare and manipulate std containers in TypePHP.

### Fixed-Size Arrays with `std::array`

Use `std::array` for matrix-like data structures where dimensions are known at compile time:

```php
<?php
use native_types;

function demoArray(): void {
    // 3x4 integer matrix
    $matrix = std::array(
        std::array(Type::Int, 4), // inner dimension
        3                         // outer dimension
    );
    $matrix[0][0] = 10;
    $matrix[2][3] = 99;
    var_dump($matrix[2][3]);   // int(99)
}

```

### Dynamic Collections with `std::vector`

Use `std::vector` for dynamically-sized lists where elements are appended at runtime:

```php
<?php
use native_types;

function demoVector(): void {
    $vec = std::vector(Type::Int);
    $vec[] = 1; 
    $vec[] = 2; 
    $vec[] = 3;
    echo $vec[1];               // 2
    echo count($vec);           // 3
}

```

### Key-Value Storage with `std::map` and `std::ordered_map`

Choose `std::ordered_map` when key order must be preserved, or `std::map` for hash-table performance:

```php
<?php
use native_types;

function demoOrderedMap(): void {
    $map = std::ordered_map(Type::String, Type::Int);
    $map["a"] = 1; 
    $map["b"] = 2;
    echo $map["a"];             // 1
}

function demoMap(): void {
    $map = std::map(Type::Int, Type::Float);
    $map[10] = 1.5; 
    $map[20] = 2.5;
    echo $map[20];              // 2.5
}

```

## Interoperability with Native C++ Code

Std containers can be passed safely to native C++ functions via `UnsafePtr` and `std::unsafe_cast()`, enabling high-performance kernels to operate on PHP data without copying. As detailed in [`docs/en/STD_CONTAINERS.md`](https://github.com/swoole/typephp/blob/main/docs/en/STD_CONTAINERS.md) (lines 62-73), this mechanism allows direct pointer access to the underlying C++ storage:

```php
// Pass vector data to a C++ kernel without copying
$vec = std::vector(Type::Float, 1000);
$ptr = std::unsafe_cast($vec); // Returns UnsafePtr<float>

```

The parser implementation in [`src/Parser/StdContainerTrait.php`](https://github.com/swoole/typephp/blob/main/src/Parser/StdContainerTrait.php) handles the translation of `std::...` calls into these typed C++ container instantiations.

## Automatic Conversion to PHP Arrays

When interoperability with legacy PHP code is required, std containers automatically convert to native PHP arrays upon assignment to untyped variables. According to [`docs/en/STD_CONTAINERS.md`](https://github.com/swoole/typephp/blob/main/docs/en/STD_CONTAINERS.md) (lines 27-33):

```php
$vec = std::vector(Type::Int);
$vec[] = 5;
$array = $vec;                 // Automatic conversion
var_dump(is_array($array));    // true

```

This conversion allows gradual adoption—performance-critical paths use std containers, while results can be passed to standard PHP functions as regular arrays.

## Summary

- **TypePHP std containers** (`std::array`, `std::vector`, `std::ordered_map`, `std::map`) provide C++ template-backed storage with PHP-like syntax
- They eliminate PHP array overhead—including `zval` storage, hash tables, and reference counting—delivering up to 10× performance gains documented in [`benchmark/bench.php`](https://github.com/swoole/typephp/blob/main/benchmark/bench.php)
- **Compile-time type checking** prevents runtime errors and enables direct memory access patterns via the AOT compiler
- **Native C++ interoperability** is supported through `UnsafePtr` and `std::unsafe_cast()` for zero-copy data exchange
- **Automatic conversion** to PHP arrays occurs when assigning to plain variables, ensuring backward compatibility

## Frequently Asked Questions

### When should I use `std::vector` instead of `std::array` in TypePHP?

**Use `std::vector`** when you need dynamically-sized collections where elements are added or removed at runtime, as it manages contiguous memory growth automatically. **Use `std::array`** only when the size is fixed at compile time, such as for mathematical matrices or fixed-size buffers, since it provides bounds checking and stack-like allocation without dynamic overhead.

### Can TypePHP std containers be passed to regular PHP functions?

**Yes**, std containers automatically convert to native PHP arrays when assigned to untyped variables or passed to functions expecting array arguments, as implemented in [`docs/en/STD_CONTAINERS.md`](https://github.com/swoole/typephp/blob/main/docs/en/STD_CONTAINERS.md). However, this conversion incurs a copy penalty, so for maximum performance, maintain container types throughout your TypePHP code or pass them to C++ kernels directly via `UnsafePtr`.

### How does compile-time type checking work with these containers?

According to [`src/Parser/StdContainerTrait.php`](https://github.com/swoole/typephp/blob/main/src/Parser/StdContainerTrait.php), the parser translates `std::vector(Type::Int)` calls into specific C++ template instantiations like `php::StdVector<php::Int>`. This allows the AOT compiler to generate type-specific machine code rather than generic `zval` operations, catching type mismatches during compilation rather than at runtime.

### What performance improvement can I expect compared to PHP arrays?

Benchmarks located in [`benchmark/bench.php`](https://github.com/swoole/typephp/blob/main/benchmark/bench.php) and referenced in [`README.md`](https://github.com/swoole/typephp/blob/main/README.md) show approximately **10× speedup** for numerical operations and tight loops. This improvement stems from eliminating zval boxing, hash table lookups, and reference counting while leveraging contiguous memory layouts that maximize CPU cache efficiency.