Нужно сохранить массив или конфиг в JSON-файл на PHP — и потом прочитать обратно без сюрпризов с кодировкой, правами и частично записанным файлом. Ниже рабочий минимум: json_encode / json_decode, атомарная запись, флаги и типичные ошибки. Для Битрикс рядом полезны Loader / ModuleManager (если JSON лежит в модуле) и кеш через TaggedCache, когда файл читают на каждом хите.
Базовая запись массива в JSON
$cars = ['lada', 'ford', 'bmw'];
$json = json_encode(
$cars,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT
);
if ($json === false) {
throw new RuntimeException('json_encode failed: ' . json_last_error_msg());
}
file_put_contents(__DIR__ . '/config.json', $json, LOCK_EX);
JSON_UNESCAPED_UNICODE оставляет кириллицу читаемой. LOCK_EX снижает риск гонки при параллельной записи. Без проверки json_encode === false легко затереть файл пустотой при невалидных данных (например, NAN или рекурсии).
Чтение и обновление
$path = __DIR__ . '/config.json';
$raw = file_get_contents($path);
if ($raw === false) {
throw new RuntimeException("Cannot read $path");
}
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$data[] = 'lada kalina';
$tmp = $path . '.tmp';
file_put_contents(
$tmp,
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
LOCK_EX
);
rename($tmp, $path); // атомарная замена на том же разделе
Второй аргумент true у json_decode даёт ассоциативный массив. JSON_THROW_ON_ERROR (PHP 7.3+) бросает JsonException вместо тишины. Схема «писать во временный файл → rename» не оставляет читателям обрезанный JSON при обрыве процесса.
Ассоциативный конфиг
$config = [
'env' => 'prod',
'features' => ['new_checkout' => true, 'cache' => true],
'limits' => ['rpm' => 120],
];
file_put_contents(
__DIR__ . '/app.json',
json_encode($config, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT)
);
Для продакшена чаще хранят секреты вне репозитория (env / vault), а в JSON — только несекретные флаги. В Битрикс настройки модуля лучше класть в Config\Option, а не в произвольный файл в upload/.
Типичные ошибки
- Кириллица как \uXXXX — добавьте
JSON_UNESCAPED_UNICODE. - Пустой файл после записи — не проверили
json_encode/ права на каталог. - Предупреждение «Invalid UTF-8» — входные строки не в UTF-8; нормализуйте до encode.
- Гонка двух воркеров —
LOCK_EX+ запись через tmp +rename. - json_decode вернул null — отличите валидный JSON
nullот ошибки черезjson_last_error()илиJSON_THROW_ON_ERROR.
Когда не нужен JSON-файл
Частые хиты лучше отдают в Redis/кеш ядра, а не в file_get_contents на каждый запрос. Большие наборы данных — в БД (ORM). JSON на диске уместен для редких конфигов, экспорта и отладки.
Итого: encode с флагами → проверка ошибки → атомарная запись. Так массив в JSON-файле переживает и кириллицу, и параллельные PHP-FPM воркеры.
