Что последнее ты писал на чистом PHP (без фреймворков)?

«Что последнее ты писал на чистом PHP (без фреймворков)?» — вопрос из категории PHP Core, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Недавно мне понадобилось создать легковесный 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 фреймворка был бы излишним.