CSV Header Validator
Checks uploaded CSV headers against required, optional, and forbidden columns.
Function signature
ogValidateCsvHeaders(headers, required_headers = array(), options = array())
Categories
- Security
Parameters
headersHeader row from a CSV file.required_headersRequired normalized header names.optionsOptional aliases, optional headers, and forbidden headers. Recognized keys: `aliases`, `forbidden`.Return value
Short public-safe status message.
- headers
- missing_required
- forbidden_present
- optional_present
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.
*/
/**
* Validates uploaded CSV headers against required, optional, forbidden, and alias rules.
*
* @param array $headers Header row from a CSV file.
* @param array $required_headers Required normalized header names.
* @param array $options Optional aliases, optional headers, and forbidden headers.
* @return array Header validation result with normalized map data.
*/
function ogValidateCsvHeaders($headers, $required_headers = array(), $options = array()) {
$result = array(
'success' => false,
'message' => '',
'data' => array()
);
if (!is_array($headers)) {
$result['message'] = 'CSV headers must be an array.';
return $result;
}
if (!is_array($required_headers)) {
$required_headers = array();
}
if (!is_array($options)) {
$options = array();
}
$aliases = array();
if (!empty($options['aliases']) && is_array($options['aliases'])) {
$aliases = $options['aliases'];
}
$forbidden = array();
if (!empty($options['forbidden']) && is_array($options['forbidden'])) {
foreach ($options['forbidden'] as $forbidden_header) {
$forbidden[] = strtolower(trim((string)$forbidden_header));
}
}
$normalized = array();
$map = array();
$errors = array();
foreach ($headers as $index => $header) {
$header = preg_replace('/^\xEF\xBB\xBF/', '', (string)$header);
$header = strtolower(trim($header));
$header = preg_replace('/[^a-z0-9_ -]+/', '', $header);
$header = preg_replace('/[ -]+/', '_', $header);
if (!empty($aliases[$header])) {
$header = strtolower(trim((string)$aliases[$header]));
}
if (empty($header)) {
$errors[] = 'Blank CSV header at position ' . (int)$index . '.';
continue;
}
if (in_array($header, $forbidden, true)) {
$errors[] = 'Forbidden CSV header: ' . $header;
}
if (in_array($header, $normalized, true)) {
$errors[] = 'Duplicate CSV header: ' . $header;
}
$normalized[] = $header;
$map[$header] = (int)$index;
}
foreach ($required_headers as $required_header) {
$required_header = strtolower(trim((string)$required_header));
if (!in_array($required_header, $normalized, true)) {
$errors[] = 'Missing required CSV header: ' . $required_header;
}
}
$result['success'] = empty($errors);
if (empty($errors)) {
$result['message'] = 'CSV headers validated.';
} else {
$result['message'] = 'CSV headers failed validation.';
}
$result['data'] = array(
'headers' => $normalized,
'map' => $map,
'errors' => $errors
);
return $result;
}