Csv Stream Writer
Streams CSV rows with proper escaping, headers, and memory-safe iteration.
Function signature
ogStreamCsvRows(rows, headers = array(), options = array())
Categories
- Security
Parameters
rowsRow data supplied for streaming, mapping, or reporting.headersStructured headers data supplied by the caller.optionsOptional policy, formatting, or behavior controls for this helper. Recognized keys: `delimiter`.Return value
Public-safe status string returned by the function.
- success
- message
- data
Compatibility
Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.
Minimum PHP version: 7.4
Security notes
Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.
Code
<?php
/*
* Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
* Free for personal and internal use. Paid project use requires visible credit
* to Jeffery L. Paris. Corporate use requires a paid license fee unless a
* separate written license states otherwise.
*/
/**
* Streams CSV rows with proper escaping, headers, and memory-safe iteration.
*
* Primary use case: Large exports.
* Typical inputs: row iterator, column headers, filename.
* Typical output: streamed response.
*
* Implementation note: Use fputcsv-style escaping in implementation.
*
* @return array Structured result data with success, message, and data keys.
*/
function ogStreamCsvRows($rows, $headers = array(), $options = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($rows)) {
$result['message'] = 'Rows must be supplied as an array.';
return $result;
}
if (!is_array($headers)) {
$headers = array();
}
if (!is_array($options)) {
$options = array();
}
$delimiter = ',';
if (!empty($options['delimiter'])) {
$delimiter = (string)$options['delimiter'];
if (strlen($delimiter) != 1) {
$delimiter = ',';
}
}
$handle = fopen('php://temp', 'r+');
if ($handle === false) {
$result['message'] = 'Temporary CSV stream could not be opened.';
return $result;
}
$row_count = 0;
if (!empty($headers)) {
fputcsv($handle, $headers, $delimiter);
}
foreach ($rows as $row) {
if (is_array($row)) {
if (!empty($headers)) {
$ordered_row = array();
foreach ($headers as $header) {
if (array_key_exists($header, $row)) {
$ordered_row[] = $row[$header];
} else {
$ordered_row[] = '';
}
}
fputcsv($handle, $ordered_row, $delimiter);
} else {
fputcsv($handle, $row, $delimiter);
}
$row_count++;
}
}
rewind($handle);
$csv = stream_get_contents($handle);
fclose($handle);
if ($csv === false) {
$csv = '';
}
$result['success'] = true;
$result['message'] = 'CSV stream prepared.';
$result['data'] = array(
'row_count' => $row_count,
'csv' => $csv,
'bytes' => strlen($csv)
);
return $result;
}