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