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

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, 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, 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 (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
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
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
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 (lines 62-73), this mechanism allows direct pointer access to the underlying C++ storage:

// 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 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 (lines 27-33):

$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
  • 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. 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, 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 and referenced in 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →