phpolars

Reference

Reading and writing

read_* functions return a DataFrame. scan_* functions return a LazyFrame, so filters and column selections are pushed into the reader. DataFrame::write*() writes a file; LazyFrame::sink*() streams a query’s result to a file without collecting it in memory.

Format Read Scan Write Sink
CSV read_csv scan_csv writeCsv sinkCsv
Parquet read_parquet scan_parquet writeParquet sinkParquet
Arrow IPC read_ipc scan_ipc writeIpc sinkIpc
NDJSON read_ndjson scan_ndjson writeNdjson sinkNdjson
JSON (array of rows) read_json writeJson
PDO database read_database writeDatabase

read_database($query, $pdo) reads a query’s result from any PDO connection. params binds placeholders through prepare() and execute(). schemaOverrides casts columns afterwards, which helps with drivers that return numbers or dates as strings: ['d' => 'Date'] parses ISO date text.

$df->writeDatabase('table', $pdo) inserts the rows in batches inside a transaction and returns the row count. ifTableExists is fail (the default), append, or replace. A new table gets portable column types: BIGINT, DOUBLE PRECISION, TEXT, BOOLEAN, DATE, and TIMESTAMP (DATETIME(6) on MySQL). List and struct values are stored as JSON text. It is tested against SQLite, PostgreSQL 17, and MySQL 8.4.

A scan runs when the query is collected. collect(engine: 'streaming'), added in v0.2.1, processes a large file in batches and keeps less of it in memory; Performance measures the difference.

Parquet, IPC, and JSON support are Cargo features. An extension built without one raises a ComputeError from that format’s functions.

$dir = sys_get_temp_dir().'/phpolars-docs';
@mkdir($dir);
$sales = read_csv('sales.csv', tryParseDates: true);

$sales->writeParquet("$dir/sales.parquet");
$sales->writeNdjson("$dir/sales.ndjson");
$sales->lazy()->filter(col('store')->eq('S2'))->sinkCsv("$dir/s2.csv");

echo read_parquet("$dir/sales.parquet")->equals($sales) ? "parquet round-trip ok\n" : "parquet differs\n";
echo scan_parquet("$dir/sales.parquet")->select(col('units')->sum())->collect()->item(), " units\n";
echo read_csv("$dir/s2.csv")->height(), " rows for S2\n";
echo read_ndjson("$dir/sales.ndjson")->schema()['date'], "\n";
parquet round-trip ok
1120 units
51 rows for S2
String

Functions

read_csv(string $source, ?bool $hasHeader = null, ?string $separator = null, mixed $nullValues = null, ?array $schemaOverrides = null, ?int $nRows = null, ?int $skipRows = null, ?int $inferSchemaLength = null, ?bool $tryParseDates = null, mixed $columns = null, ?array $schema = null, ?string $commentPrefix = null, mixed $quoteChar = null, ?string $eolChar = null, ?string $encoding = null, ?bool $ignoreErrors = null, ?bool $missingUtf8IsEmptyString = null, ?bool $truncateRaggedLines = null, ?bool $decimalComma = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, ?int $skipRowsAfterHeader = null, ?array $newColumns = null, ?bool $raiseIfEmpty = null, ?bool $glob = null): Phpolars\DataFrame
read_database(string $query, mixed $connection, ?array $params = null, ?array $schemaOverrides = null): Phpolars\DataFrame
read_ipc(string $source, ?int $nRows = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, mixed $columns = null): Phpolars\DataFrame
read_ipc_schema(string $source): array
read_ipc_stream(string $source, mixed $columns = null, ?int $nRows = null): Phpolars\DataFrame
read_json(string $source, ?array $schema = null, ?array $schemaOverrides = null, ?int $inferSchemaLength = null): Phpolars\DataFrame
read_ndjson(string $source, ?int $nRows = null, ?int $inferSchemaLength = null, ?array $schema = null, ?array $schemaOverrides = null, ?bool $ignoreErrors = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, mixed $columns = null): Phpolars\DataFrame
read_parquet(string $source, mixed $columns = null, ?int $nRows = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, ?string $parallel = null, ?bool $useStatistics = null, ?bool $hivePartitioning = null, ?bool $glob = null, ?bool $allowMissingColumns = null, ?string $includeFilePaths = null): Phpolars\DataFrame
read_parquet_schema(string $source): array
scan_csv(string $source, ?bool $hasHeader = null, ?string $separator = null, mixed $nullValues = null, ?array $schemaOverrides = null, ?int $nRows = null, ?int $skipRows = null, ?int $inferSchemaLength = null, ?bool $tryParseDates = null, mixed $columns = null, ?array $schema = null, ?string $commentPrefix = null, mixed $quoteChar = null, ?string $eolChar = null, ?string $encoding = null, ?bool $ignoreErrors = null, ?bool $missingUtf8IsEmptyString = null, ?bool $truncateRaggedLines = null, ?bool $decimalComma = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, ?int $skipRowsAfterHeader = null, ?array $newColumns = null, ?bool $raiseIfEmpty = null, ?bool $glob = null): Phpolars\LazyFrame
scan_ipc(string $source, ?int $nRows = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null): Phpolars\LazyFrame
scan_ndjson(string $source, ?int $nRows = null, ?int $inferSchemaLength = null, ?array $schema = null, ?array $schemaOverrides = null, ?bool $ignoreErrors = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null): Phpolars\LazyFrame
scan_parquet(string $source, ?int $nRows = null, ?string $rowIndexName = null, ?int $rowIndexOffset = null, ?string $parallel = null, ?bool $useStatistics = null, ?bool $hivePartitioning = null, ?bool $glob = null, ?bool $allowMissingColumns = null, ?string $includeFilePaths = null): Phpolars\LazyFrame

From phpstats/phpolars@8487062.