Skip to content
Search

Flow PHP Extension

Flow stores durable datasets (to_floe()) and caches intermediate ones (DataFrame::cache(), external-sort spill buckets) using the native Floe binary format (.floe) — the schema is written once per section and rows carry raw values only, which makes both the payload and the hydration dramatically cheaper than native PHP serialize()/unserialize().

This extension encodes and decodes Floe frames natively in Rust via ext-php-rs. The pure-PHP implementation in Flow\Floe (flow-php/etl) is the canonical behavior reference and works without the extension — loading it is purely an optimization. File header and footer assembly always stay in PHP.

You never need to call this extension directly. Flow\Floe\FloeReader/FloeWriter — used by from_floe()/to_floe(), the cache and the external-sort buckets cache — route ROW/SCHEMA frame bodies to it automatically when extension_loaded('flow_php') is true.

Loading the Extension

In php.ini

extension = flow_php

During Development

php -d extension=./ext/modules/flow_php.so your_script.php

Usage

The extension is used implicitly through the ETL cache:

<?php

use function Flow\ETL\DSL\{df, from_array, to_stream};

df()
    ->read(from_array($bigDataset))
    ->cache('my-dataset') // serialized with the extension when loaded
    ->write(to_stream(__DIR__ . '/output.csv'))
    ->run();

The low-level API works on bare frame bodies (FloeReader/FloeWriter add the framing):

<?php

use Flow\Floe\RowsDecoder;
use Flow\Floe\RowsEncoder;

$decoder = new RowsDecoder();
$decoder->schema($schemaFrameBody);
$row = $decoder->row($rowFrameBody);              // Flow\ETL\Row
$rows = $decoder->rows([$rowFrameBody, ...]);     // batched: Flow\ETL\Rows

$encoder = new RowsEncoder();
$encoder->schema($schemaFrameBody);
$rowFrameBody = $encoder->row($row);              // byte-identical to Flow\Floe\RowEncoder

$segments = (new RowsEncoder())->rows($rows);     // batched: framed ROW frames per section segment,
                                                  // list of Flow\Floe\FrameSegment

All extension failures throw Flow\Floe\Exception\ExtensionException; FloeReader/FloeWriter wrap it as Flow\Floe\Exception\FloeException. There is no silent fallback to the PHP engine.

Found a typo or an outdated section? Edit this page on GitHub


Contributors

Built in the open.

Join us on GitHub
scroll back to top