Last updated: August 29, 2026.
A scalable CSV import keeps only one row in memory. Validate the header once, reject malformed records with line numbers, and write database changes in controlled batches.
Stream with SplFileObject
<?php
$file = new SplFileObject(__DIR__ . '/customers.csv', 'r');
$file->setFlags(SplFileObject::READ_CSV | SplFileObject::SKIP_EMPTY);
$file->setCsvControl(',', '"', '');
$header = $file->fgetcsv();
if ($header !== ['email', 'name', 'country']) throw new RuntimeException('Unexpected header.');
foreach ($file as $row) {
if ($row === [null] || count($row) !== 3) continue;
if (!filter_var($row[0], FILTER_VALIDATE_EMAIL)) continue;
// Persist with a prepared statement.
}Make imports predictable
- Require an explicit delimiter and encoding.
- Log row numbers and rejection reasons.
- Use prepared statements and transaction batches.
- Move long imports to a background job.
Design the import as a resumable process
Streaming keeps memory stable, but a production import also needs row-level validation, useful error reporting, and controlled database transactions. Record a line number or source identifier for each rejected row.
Test quoted delimiters, embedded line breaks, blank rows, a missing final newline, and an invalid header. Compare accepted plus rejected rows with the input count.
- Use prepared statements.
- Commit in bounded batches.
- Move long imports to a job worker.
Keep resource limits explicit and make failure cleanup part of the example. Log enough context to diagnose the operation without recording passwords, private message bodies, or uploaded file contents.
Continue with CSV encoding repair, temporary files, and ZIP archives.
Practical implementation check
Put the operation in a small function or service with explicit inputs and a clear failure result. Test invalid input, missing extensions, permission failures, and concurrent requests. Production logs should identify the operation and record ID without storing secrets or private content. Clean up partially created files or queue records when any later step fails.
Reference: PHP SplFileObject CSV reference.