Методы записи JSON в файл средствами PHP

Раздел: Работа с JSON в PHP -> Сохранение JSON

Сохранение JSON в файл является частой задачей при работе с PHP. Основной и наиболее эффективный способ - использование функции file_put_contents в сочетании с json_encode. Этот метод объединяет создание или перезапись файла и запись данных одной строкой, минимально расходуя ресурсы.


$data = ['user' => 'Иван', 'age' => 30, 'roles' => ['admin', 'editor']];
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
file_put_contents('data.json', $json);
  

Php сохранить json (сохранение json в файл на php)

Параметр JSON_UNESCAPED_UNICODE предотвращает преобразование кириллицы в юникод-последовательности (\uXXXX), а JSON_PRETTY_PRINT форматирует вывод с отступами, делая файл читаемым для человека.

Типичная ошибка: отсутствие прав на запись в папку. Решение - проверка is_writable() перед записью или установка корректных прав chmod. Другая проблема - недопустимые значения в данных (например, ресурсы или объекты без JsonSerializable). В этом случае json_encode вернёт false, что нужно проверять.

Как выполнить запись с пошаговым контролем каждого этапа?

Использование пары fopen / fwrite / fclose даёт возможность управлять буферизацией и проверять промежуточные результаты.


$file = fopen('data.json', 'w');
if ($file) {
    $json = json_encode($data, JSON_UNESCAPED_UNICODE);
    fwrite($file, $json);
    fclose($file);
} else {
    // обработка ошибки
}
  

Такой подход полезен при необходимости дописывать данные частями или использовать нестандартные потоки.

Ошибка: забытый вызов fclose приводит к утечке дескриптора. Для предотвращения стоит оборачивать код в try-finally или использовать автоматическое закрытие через file_put_contents.

Как избежать повреждения файла при одновременном доступе?

При многопоточности или параллельных запросах к одному файлу следует применить блокировку flock.


$file = fopen('data.json', 'c');
if (flock($file, LOCK_EX)) {
    $json = json_encode($data, JSON_UNESCAPED_UNICODE);
    ftruncate($file, 0);   // очистка
    fwrite($file, $json);
    flock($file, LOCK_UN);
}
fclose($file);
  

Режим 'c' не урезает файл при открытии, а ftruncate очищает его перед записью.

Ошибка: если блокировка не освобождена, другие процессы будут ждать или получат отказ. Всегда следует использовать LOCK_UN или дождаться завершения.

Как перехватить ошибки кодирования JSON?

Начиная с PHP 7.3 можно указать флаг JSON_THROW_ON_ERROR, чтобы вместо возврата false выбрасывалось исключение.


try {
    $json = json_encode($data, JSON_THROW_ON_ERROR);
    file_put_contents('data.json', $json);
} catch (JsonException $e) {
    // логирование или уведомление
}
  

Цель - безусловное обнаружение ошибок сериализации на этапе разработки.

Проблема: в более старых версиях PHP константа не определена. Аналог - ручная проверка json_last_error().

Как автоматически создавать папку для файла?

Если целевая директория может отсутствовать, её нужно создать рекурсивно через mkdir.


$path = 'backups/data.json';
$dir = dirname($path);
if (!is_dir($dir)) {
    mkdir($dir, 0777, true);
}
file_put_contents($path, json_encode($data, JSON_UNESCAPED_UNICODE));
  

Параметр true в mkdir разрешает создание вложенных папок.

Ошибка: недостаточно прав на создание директории. Решение - проверка успешности mkdir или предварительная настройка прав.

Как добавить метаданные (время, версию) в имя файла?

Для хранения истории изменений можно динамически формировать имя, включая метку времени.


$filename = 'data_' . date('Ymd_His') . '.json';
file_put_contents($filename, json_encode($data, JSON_PRETTY_PRINT));
  

Такой подход удобен для резервного копирования или аудита.

Предостережение: при большом количестве файлов может потребоваться ротация или очистка. Также возможно пересечение имён при одновременных операциях в одну секунду - стоит добавить микросекунды (u).

Расширенные примеры сохранения JSON

Пример 1: Поточная запись больших массивов

Если данные очень велики и не помещаются в память, следует кодировать и записывать поэтапно. Ниже пример с использованием генератора.

Пример

function generateLargeArray(): Generator {
    for ($i = 0; $i < 100000; $i++) {
        yield ['id' => $i, 'value' => str_repeat('x', 1000)];
    }
}

$file = fopen('large.json', 'w');
fwrite($file, '[');
$first = true;
foreach (generateLargeArray() as $item) {
    if (!$first) fwrite($file, ',');
    fwrite($file, json_encode($item, JSON_UNESCAPED_UNICODE));
    $first = false;
}
fwrite($file, ']');
fclose($file);
Файл large.json содержит валидный JSON-массив из 100 000 элементов, сформированный без полной загрузки в память.

Пример 2: Сохранение с шифрованием содержимого

Для хранения конфиденциальных данных можно закодировать JSON в base64 (но учтите, что это не защита, а лишь преобразование).

Пример

$data = ['password' => 'secret'];
$json = json_encode($data);
$encoded = base64_encode($json);
file_put_contents('secret.data', $encoded);
Содержимое файла secret.data: eyJwYXNzd29yZCI6InNlY3JldCJ9

Пример 3: Пользовательский класс с интерфейсом JsonSerializable

Объекты, реализующие JsonSerializable, могут управлять своей JSON-сериализацией.

Пример

class User implements JsonSerializable {
    public function __construct(
        private string $name,
        private int $age,
        private string $password  // не включать в JSON
    ) {}

    public function jsonSerialize(): mixed {
        return ['name' => $this->name, 'age' => $this->age];
    }
}

$user = new User('Анна', 28, 'hidden');
file_put_contents('user.json', json_encode($user, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
{
    "name": "Анна",
    "age": 28
}

Пример 4: Сохранение с кастомными опциями и сравнение размера

Использование разных комбинаций флагов влияет на размер и читаемость файла.

Пример

$data = ['url' => 'https://example.com/path?q=test&lang=ru'];

$compact = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$pretty  = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

file_put_contents('compact.json', $compact);
file_put_contents('pretty.json', $pretty);

echo 'Compact size: ' . strlen($compact) . ' bytes\n';
echo 'Pretty size: ' . strlen($pretty) . ' bytes';
Compact size: 55 bytes
Pretty size: 76 bytes

Пример 5: Запись в удалённый ресурс через обёртку потока

PHP позволяет записывать данные не только в локальный файл, но и, например, на FTP-сервер.

Пример

$json = json_encode($data);
$options = ['ftp' => [
    'overwrite' => true,
    'username'  => 'user',
    'password'  => 'pass'
]];
$stream = fopen('ftp://example.com/data.json', 'w', false, stream_context_create($options));
fwrite($stream, $json);
fclose($stream);
Файл data.json будет записан на удалённый FTP-сервер при корректных учётных данных.

Сохранение JSON в файл на PHP - comments

En
Php сохранить json (php)