Read Large CSV Files without Exhausting PHP Memory

Last updated: August 28, 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.

Reference: PHP SplFileObject CSV reference.

admin

admin