Ответ
Недавно мне понадобилось создать легковесный CLI-скрипт для обработки и импорта большого CSV-файла (около 100k записей) в базу данных. Использование чистого PHP без фреймворка было оправдано для максимальной скорости выполнения и минимального потребления памяти.
Задача: Преобразовать данные из CSV, провести валидацию, и пакетно вставить их в MySQL.
Ключевые моменты реализации:
#!/usr/bin/env php
<?php
// 1. Парсинг аргументов командной строки
$options = getopt('f:', ['file:']);
$csvFile = $options['f'] ?? $options['file'] ?? 'php://stdin';
// 2. Подключение к БД с PDO
$pdo = new PDO('mysql:host=localhost;dbname=import_db', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 3. Потоковое чтение CSV файла
$handle = fopen($csvFile, 'r');
if ($handle === false) {
throw new RuntimeException('Cannot open file: ' . $csvFile);
}
$batchSize = 1000;
$batchData = [];
$header = fgetcsv($handle); // Первая строка - заголовки
// 4. Подготовленный запрос для пакетной вставки
$stmt = $pdo->prepare(
'INSERT INTO products (sku, name, price, quantity) VALUES (?, ?, ?, ?)'
);
while (($row = fgetcsv($handle)) !== false) {
// 5. Валидация и преобразование данных
$sku = trim($row[0]);
if (empty($sku)) {
continue; // Пропуск записей без SKU
}
$price = (float) str_replace(',', '.', $row[2]);
$batchData[] = [$sku, $row[1], $price, (int)$row[3]];
// 6. Пакетная вставка при достижении лимита
if (count($batchData) >= $batchSize) {
executeBatch($pdo, $stmt, $batchData);
$batchData = [];
}
}
// Вставка оставшихся данных
if (!empty($batchData)) {
executeBatch($pdo, $stmt, $batchData);
}
fclose($handle);
echo 'Import completed successfully.' . PHP_EOL;
/**
* Выполняет пакетную вставку данных.
*/
function executeBatch(PDO $pdo, PDOStatement $stmt, array $batch): void
{
$pdo->beginTransaction();
try {
foreach ($batch as $rowData) {
$stmt->execute($rowData);
}
$pdo->commit();
} catch (PDOException $e) {
$pdo->rollBack();
throw $e;
}
}
Также я периодически пишу на чистом PHP простые REST-эндпоинты для интеграций или утилиты для администрирования сервера, где overhead фреймворка был бы излишним.