CSV — это такая мина под задницей любого разработчика. Сначала тебе присылают файлик на 200 строк — всё норм, можно хоть fgetcsv() ковырять. Но потом в продакшн заваливается монстр на 5 гигабайт, и тут выясняется, что твой Laravel и память сервера дружно ложатся. Нет, ребята, это не "просто импортировать". Это ад, где каждый лишний foreach может убить твой процесс. .

Вариант 1. Spatie Simple Excel — быстро, но не для монстров

Spatie выпустили свой пакет — spatie/simple-excel. Ставится как обычно:

composer require spatie/simple-excel

Для небольших файлов — норм тема. Синтаксис приятный, читаешь и пишешь строки без лишней возни.

use Spatie\SimpleExcel\SimpleExcel;

$rows = SimpleExcel::read('file.csv')->getRows();

foreach ($rows as $row) {
    // ковыряешь строки
}

И запись так же просто:

SimpleExcel::write('file.csv', $data);

Проблема в том, что если у тебя CSV под гигабайт — этот пакет превращается в кирпич. Он не жрёт стриминг как надо, память начинает течь, и сервер задыхается. То есть — да, можно юзать для файлов «чтобы было», но не для реальных бигдат.

Вариант 2. Laravel Excel — инструмент для адекватных людей

Настоящая пушка для CSV — это maatwebsite/laravel-excel. Ставим:

composer require maatwebsite/excel

Что в нём нравится — можно резать файл на чанки и жрать их по кускам, не загружая всю махину в память.

use Maatwebsite\Excel\Facades\Excel;
use App\Imports\UsersImport;

Excel::filter('chunk')->import(new UsersImport, 'users.csv');

А в импорте ты просто пишешь размер куска:

public function chunkSize(): int
{
    return 1000; // по тысяче строк за раз
}

И это реально спасает. Потому что PHP и 10к строк жрёт легко, а вот миллион — убьёт сервер.

Очереди: твой друг, если файл жирный

Если CSV гигантский, загоняй обработку в очереди. Laravel умеет это делать. Берёшь каждую строку, пихаешь в job и пинаешь очередь:

use Illuminate\Support\Facades\Queue;

$rows = Excel::toCollection(new UsersImport, 'users.csv');

foreach ($rows as $row) {
    Queue::push(new ProcessRowJob($row));
}

Да, это чуть дольше, но зато скрипт не упадёт через 30 секунд. Сервак будет ковырять файл, пока не доковыряет. Главное — не забудь поставить нормального воркера, а не держать очередь на database driver.

Оптимизация, без которой всё равно сдохнешь

  • Стриминг. Laravel Excel умеет читать файл стримом. Это значит, что память жрётся минимально, а не как у жирного питона, который загрузил всё в RAM и сдох.
  • PHP-конфиги. Увеличь memory_limit и max_execution_time, иначе PHP тебя предаст.
  • База. CSV обычно не просто читают — их грузят в базу. И вот там без индексов ты превратишь insert в кладбище. Индексируй, иначе будешь ждать пока сервер остынет.

Реальность такая

Большие CSV — это не «фича», это боль. Laravel тебе тут не враг, но и не спаситель. Если файл больше пары гигабайт — забудь про романтику, ставь стриминг, очереди и готовься к долгому ковырянию. А если у тебя просто список клиентов из CRM на 5 тысяч строк — не строй из этого трагедию. Даже fgetcsv() справится. Главное — не пытайся проглотить всё сразу.