readFirstLine($path); if ($firstLine === null) { return [$bestDelim, []]; } $maxCount = 0; foreach ($delims as $d) { $row = str_getcsv($firstLine, $d); $count = is_array($row) ? count($row) : 0; if ($count > $maxCount) { $maxCount = $count; $bestDelim = $d; $bestCols = $row; } } if (!$hasHeader) { // return positional indices 0..N-1 $cols = []; for ($i = 0; $i < $maxCount; $i++) { $cols[] = (string) $i; } return [$bestDelim, $cols]; } // Clean header names $clean = array_map(function ($v) { $v = trim((string) $v); $v = preg_replace('/\s+/', ' ', $v); return $v; }, $bestCols); return [$bestDelim, $clean]; } /** * Parse columns from CSV using a specific delimiter. If $hasHeader is false, * returns positional indices instead of header names. */ public function parseColumnsFromCsv(string $path, string $delimiter, bool $hasHeader): array { $firstLine = $this->readFirstLine($path); if ($firstLine === null) { return []; } $row = str_getcsv($firstLine, $delimiter); $count = is_array($row) ? count($row) : 0; if ($hasHeader) { return array_map(function ($v) { $v = trim((string) $v); $v = preg_replace('/\s+/', ' ', $v); return $v; }, $row ?: []); } $cols = []; for ($i = 0; $i < $count; $i++) { $cols[] = (string) $i; } return $cols; } }