Fscanf: примеры (PHP)

Использование fscanf для форматированного чтения данных в PHP
Раздел: Работа с файлами
fscanf(resource $stream, string $format, mixed &...$vars): array|int|false|null

Основы функции fscanf

Назначение функции

Функция fscanf() выполняет форматированное чтение данных из файла. Она аналогична функции sscanf(), но работает с файловым указателем вместо строки.

Синтаксис и параметры

Сигнатура функции:
mixed fscanf(resource $stream, string $format, mixed &...$vars)

  • $stream — файловый указатель, полученный функцией fopen()
  • $format — строка форматирования, определяющая ожидаемые данные
  • $vars — необязательные переменные, в которые будут помещены считанные значения
Спецификаторы формата
  • %d, %u — целые числа (со знаком и без)
  • %f, %F — числа с плавающей точкой
  • %s — строка (до следующего пробельного символа)
  • %c — один символ
  • %[^\n] — строка до символа новой строки
  • %x — шестнадцатеричное число
  • %o — восьмеричное число

Базовые примеры использования

Чтение отдельных значений
$fp = fopen('data.txt', 'r');
// Содержимое data.txt: "Иван 25 75.5"
$result = fscanf($fp, "%s %d %f");
print_r($result);
fclose($fp);
Array
(
    [0] => Иван
    [1] => 25
    [2] => 75.5
)
Запись значений в переменные
$fp = fopen('data.txt', 'r');
// Содержимое data.txt: "Товар 42 199.99"
fscanf($fp, "%s %d %f", $name, $quantity, $price);
echo "$name: $quantity шт., цена $price";
fclose($fp);
Товар: 42 шт., цена 199.99
Чтение до конца строки
$fp = fopen('text.txt', 'r');
// Содержимое text.txt: "Пример текста для чтения"
fscanf($fp, "%[^\n]", $fullLine);
echo $fullLine;
fclose($fp);
Пример текста для чтения

Альтернативные функции в PHP

fgets() и explode()

Комбинация fgets() и explode() проще для чтения строк с разделителями, но менее гибка для сложных форматов.

$line = fgets($fp);
$parts = explode(' ', $line);
sscanf()

Функция sscanf() работает аналогично, но читает из строки вместо файла. Полезно, когда данные уже в строковой переменной.

$data = "Январь 31 2023";
sscanf($data, "%s %d %d", $month, $day, $year);
file() и list()

Для простых случаев чтения всего файла в массив строк, с последующей обработкой каждой строки.

Когда что использовать
  • fscanf() — для структурированных данных с известным форматом
  • fgets() + explode() — для CSV-подобных данных с простыми разделителями
  • sscanf() — когда данные уже в строковой переменной
  • file() — для чтения всего файла без сложного парсинга

Аналоги в других языках

Fscanf в Python

В Python используется метод read() с распаковкой или модуль struct для бинарных данных.

# Python аналог
with open('data.txt', 'r') as f:
    name, age, score = f.read().split()
    age = int(age)
    score = float(score)
JavaScript (Node.js)

В Node.js чтение файлов асинхронное, форматирование выполняется после получения данных.

// JavaScript пример
const fs = require('fs');
fs.readFile('data.txt', 'utf8', (err, data) => {
    const [name, age, score] = data.split(' ');
    console.log(name, parseInt(age), parseFloat(score));
});
C/C++

Синтаксис fscanf() в C очень похож на PHP, так как PHP унаследовал многие функции из C.

// C аналог
FILE *fp = fopen("data.txt", "r");
char name[50];
int age;
float score;
fscanf(fp, "%s %d %f", name, &age, &score);
fclose(fp);
MySQL LOAD DATA

Для импорта структурированных данных из файлов в таблицы.

-- Импорт данных в MySQL
LOAD DATA INFILE 'data.txt'
INTO TABLE users
FIELDS TERMINATED BY ' ';

Типичные ошибки

Неверный указатель файла
// Ошибка: файл не открыт
$result = fscanf($fp, "%s %d");
// Warning: fscanf() expects parameter 1 to be resource, bool given
Несоответствие формата данным
$fp = fopen('data.txt', 'r');
// Содержимое: "Строка текст"
// Ожидается число, но его нет
fscanf($fp, "%d", $number);
// $number останется null, функция вернет null или 0
fclose($fp);
Игнорирование возвращаемого значения
$fp = fopen('data.txt', 'r');
while (fscanf($fp, "%s", $word)) { // Бесконечный цикл
    echo $word;
}
// Нужно проверять количество считанных значений
while (fscanf($fp, "%s", $word) === 1) {
    echo $word;
}
fclose($fp);
Проблемы с кодировкой
// Файл в UTF-8, но чтение как ASCII
$fp = fopen('utf8.txt', 'r');
// Мультибайтовые символы могут читаться некорректно
fscanf($fp, "%s", $word);

Изменения в версиях PHP

PHP 7.2.0

Добавлена поддержка возврата null при неудачном чтении, когда не указаны переменные для значений.

PHP 8.0.0

Параметр $vars теперь является необязательным. Если переменные не переданы, функция возвращает массив или null.

// До PHP 8.0
$result = fscanf($fp, "%s %d", $var1, $var2);
// PHP 8.0+
$result = fscanf($fp, "%s %d"); // Возвращает массив или null
Совместимость с типами

В PHP 8 усилена строгая типизация. Некорректные преобразования типов могут вызывать предупреждения.

Расширенные примеры

Чтение конфигурационного файла
Пример php
$fp = fopen('config.txt', 'r');
$config = [];
while ($line = fgets($fp)) {
    if (trim($line) === '' || $line[0] === '#') continue;
    fscanf($fp, "%[^=]=%[^\n]", $key, $value);
    $config[trim($key)] = trim($value);
}
fclose($fp);
print_r($config);
// config.txt:
// host=localhost
// port=3306
// user=root
Array
(
    [host] => localhost
    [port] => 3306
    [user] => root
)
Обработка CSV с разными типами данных
Пример php
$fp = fopen('products.csv', 'r');
$products = [];
while (fscanf($fp, "%[^,],%d,%f", $name, $qty, $price) === 3) {
    $products[] = [
        'name' => $name,
        'quantity' => $qty,
        'price' => $price
    ];
    // Пропуск оставшейся части строки
    fgets($fp);
}
fclose($fp);
Чтение данных фиксированной ширины
Пример php
// Формат: ID(4 символа) Name(20 символов) Age(3 символа)
$fp = fopen('fixed_width.txt', 'r');
while (!feof($fp)) {
    // Чтение конкретного количества символов
    $id = fread($fp, 4);
    $name = fread($fp, 20);
    $age = fread($fp, 3);
    fscanf($fp, "%*[\n]"); // Пропуск новой строки
    echo "ID: $id, Name: $name, Age: $age";
}
fclose($fp);
Парсинг лог-файлов
Пример php
$fp = fopen('access.log', 'r');
$stats = [];
while (!feof($fp)) {
    // Формат: IP - [дата] "метод URL протокол" код размер
    if (fscanf($fp, "%s - - [%[^]]] \"%s %s %[^\"]\" %d %d",
        $ip, $date, $method, $url, $proto, $code, $size) === 7) {
        if (!isset($stats[$ip])) $stats[$ip] = 0;
        $stats[$ip]++;
    }
}
fclose($fp);
arsort($stats);
print_r(array_slice($stats, 0, 5));
Чтение двоичных данных
Пример php
$fp = fopen('binary.dat', 'rb');
// Чтение заголовка: сигнатура (4 байта) + версия (1 байт)
$signature = fread($fp, 4);
// Использование unpack для двоичных данных предпочтительнее
$header = unpack('Cversion', fread($fp, 1));
echo "Сигнатура: $signature, Версия: {$header['version']}";
fclose($fp);

PHP fscanf function comments

En
Fscanf Parses input from a file according to a format