Export Stream Planner
Plans streamed CSV/JSON exports with headers, chunk size, and filename policy.
Function signature
ogPlanExportStream(request = array(), policy = array())
Categories
- Security
Parameters
requestExport request data. Recognized keys: `chunk_size`, `columns`, `format`.policyAllowed formats, columns, filename prefix, and chunk limits. Recognized keys: `allowed_columns`, `allowed_formats`, `filename_prefix`.Return value
Short public-safe status message.
- format
- filename
- content_type
- columns
- chunk_size
- streaming
Compatibility
Existing function name and call order preserved; metadata signature corrected to source.
Minimum PHP version: 7.4
Security notes
Validate request method, identity, permissions, policy arrays, URLs, signatures, and caller-owned allowlists before use; keep secrets and internal paths out of public output.
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.
*/
/**
* Plans streamed CSV/JSON exports with headers, chunk size, and filename policy.
*
* The helper does not execute queries or buffer data. It returns a safe export plan that a controller
* can use for explicit streaming output.
*
* @param array $request Export request data.
* @param array $policy Allowed formats, columns, filename prefix, and chunk limits.
* @return array Export stream plan.
*/
function ogPlanExportStream($request = array(), $policy = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($request)) {
$result['message'] = 'Export request must be an array.';
return $result;
}
if (!is_array($policy)) {
$policy = array();
}
$allowed_formats = array('csv', 'json');
if (!empty($policy['allowed_formats']) && is_array($policy['allowed_formats'])) {
$allowed_formats = $policy['allowed_formats'];
}
$format = 'csv';
if (!empty($request['format'])) {
$format = strtolower(trim((string)$request['format']));
}
if (!in_array($format, $allowed_formats, true)) {
$result['message'] = 'Export format is not allowed.';
return $result;
}
$allowed_columns = array();
if (!empty($policy['allowed_columns']) && is_array($policy['allowed_columns'])) {
$allowed_columns = $policy['allowed_columns'];
}
$columns = array();
if (!empty($request['columns']) && is_array($request['columns'])) {
foreach ($request['columns'] as $column) {
$column = preg_replace('/[^a-zA-Z0-9_]/', '', (string)$column);
if (!empty($column) && (empty($allowed_columns) || in_array($column, $allowed_columns, true))) {
$columns[] = $column;
}
}
}
if (empty($columns) && !empty($allowed_columns)) {
$columns = $allowed_columns;
}
$chunk_size = 500;
if (!empty($request['chunk_size'])) {
$chunk_size = (int)$request['chunk_size'];
}
if ($chunk_size < 50) {
$chunk_size = 50;
}
if ($chunk_size > 5000) {
$chunk_size = 5000;
}
$prefix = 'phpog-export';
if (!empty($policy['filename_prefix'])) {
$prefix = preg_replace('/[^a-zA-Z0-9_-]/', '', (string)$policy['filename_prefix']);
}
$filename = $prefix . '-' . gmdate('Ymd-His') . '.' . $format;
$content_type = 'text/csv';
if ($format == 'json') {
$content_type = 'application/json';
}
$result['success'] = true;
$result['message'] = 'Export stream plan built.';
$result['data'] = array(
'format' => $format,
'filename' => $filename,
'content_type' => $content_type,
'columns' => $columns,
'chunk_size' => $chunk_size,
'streaming' => true
);
return $result;
}