CSV Row Mapper
Maps CSV rows to internal field names using validated headers and defaults.
Function signature
ogMapCsvRowToFields(header_map, row_values, field_map, defaults = array())
Categories
- Security
Parameters
header_mapCSV header name to zero-based column index map.row_valuesRaw row values from the CSV parser.field_mapInternal field name to CSV header name map.defaultsOptional default values by internal field name.Return value
Short public-safe status message.
- row
- missing_fields
- warnings
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, 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.
*/
/**
* Maps one CSV row into internal field names using a validated header map.
*
* This helper does not guess column meaning. The caller provides the field map
* so imports stay explicit and auditable.
*
* @param array $header_map CSV header name to zero-based column index map.
* @param array $row_values Raw row values from the CSV parser.
* @param array $field_map Internal field name to CSV header name map.
* @param array $defaults Optional default values by internal field name.
* @return array Structured mapping result with mapped values, warnings, and missing fields.
*/
function ogMapCsvRowToFields($header_map, $row_values, $field_map, $defaults = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($header_map)) {
$result['message'] = 'Header map must be an array.';
return $result;
}
if (!is_array($row_values)) {
$result['message'] = 'Row values must be an array.';
return $result;
}
if (!is_array($field_map)) {
$result['message'] = 'Field map must be an array.';
return $result;
}
if (!is_array($defaults)) {
$defaults = array();
}
$normalized_headers = array();
foreach ($header_map as $header_name => $column_index) {
$header_name = preg_replace('/^\xEF\xBB\xBF/', '', (string)$header_name);
$header_key = strtolower(trim($header_name));
if (!empty($header_key)) {
$normalized_headers[$header_key] = (int)$column_index;
}
}
$mapped = array();
$missing = array();
$warnings = array();
foreach ($field_map as $internal_field => $csv_header) {
$internal_field = trim((string)$internal_field);
$csv_header_key = strtolower(trim((string)$csv_header));
if (empty($internal_field)) {
$warnings[] = 'Blank internal field name skipped.';
continue;
}
if (!array_key_exists($csv_header_key, $normalized_headers)) {
if (array_key_exists($internal_field, $defaults)) {
$mapped[$internal_field] = $defaults[$internal_field];
} else {
$mapped[$internal_field] = '';
$missing[] = $internal_field;
}
continue;
}
$column_index = $normalized_headers[$csv_header_key];
if (array_key_exists($column_index, $row_values)) {
if (is_scalar($row_values[$column_index])) {
$mapped[$internal_field] = trim((string)$row_values[$column_index]);
} else {
$mapped[$internal_field] = $row_values[$column_index];
}
} else {
if (array_key_exists($internal_field, $defaults)) {
$mapped[$internal_field] = $defaults[$internal_field];
} else {
$mapped[$internal_field] = '';
$missing[] = $internal_field;
}
}
}
$result['success'] = true;
$result['message'] = 'CSV row mapped.';
$result['data'] = array(
'row' => $mapped,
'missing_fields' => $missing,
'warnings' => $warnings
);
return $result;
}