Здравствуйте! Помогите пожалуйста решить проблему - у меня есть файл kursNBU.json с таким содержимым: Код (Text): [ { "r030":643,"txt":"Російський рубль","rate":0.40877,"cc":"RUB","exchangedate":"15.07.2019" }, { "r030":840,"txt":"Долар США","rate":25.760584,"cc":"USD","exchangedate":"15.07.2019" }, { "r030":933,"txt":"Бiлоруський рубль","rate":12.66374,"cc":"BYN","exchangedate":"15.07.2019" }, { "r030":978,"txt":"Євро","rate":28.988385,"cc":"EUR","exchangedate":"15.07.2019" } ] В этих данных ключ это "r030", он обозначает код валют и является статическим. Я создал задачу cron которая запускает скрипт который должен обновить значения для ключей "rate" и "exchangedate". Вот мой код: PHP: <?php $json = @file_get_contents("https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json"); if ( $json !== false ) { $kurs_new = json_decode($json); $cron_curs = file_get_contents( __DIR__ . "/cursNBU.json"); $kurs_old = json_decode($cron_curs); foreach ( $kurs_new as $cur ) { foreach ( $kurs_old as $item ) { if ( $item->r030 == $cur->r030 ) { $item->rate = $cur->rate; $item->exchangedate = $cur->exchangedate; } } } } // преобразовываем его в json вид $json_new = json_encode($kurs_old); // открываем файл $file = fopen(__DIR__ . '/kursNBU.json', 'w'); // и записываем туда данные $write = fwrite($file, $json_new); //закрываем файл fclose($file); // Очистить переменные unset($kurs_new); unset($kurs_old); В итоге после выполнения cron задачи в файле kursNBU.json всё полностью стирается и записывается значение null Файл php и файл json лежат рядом в одной папке.
Файл у вас kursNBU.json, а прочитать пытаетесь PHP: $cron_curs = file_get_contents( __DIR__ . "/cursNBU.json");
Спасибо! Теперь обновление файла идёт, но есть проблема. Вот как данные записались: Код (Text): [ { "r030":643,"txt":"\u0420\u043e\u0441\u0456\u0439\u0441\u044c\u043a\u0438\u0439 \u0440\u0443\u0431\u043b\u044c","rate":0.408770000000000022222224060897133313119411468505859375,"cc":"RUB","exchangedate":"15.07.2019" }, { "r030":840,"txt":"\u0414\u043e\u043b\u0430\u0440 \u0421\u0428\u0410","rate":25.76058400000000148111212183721363544464111328125,"cc":"USD","exchangedate":"15.07.2019" }, { "r030":933,"txt":"\u0411i\u043b\u043e\u0440\u0443\u0441\u044c\u043a\u0438\u0439 \u0440\u0443\u0431\u043b\u044c","rate":12.663740000000000662794263917021453380584716796875,"cc":"BYN","exchangedate":"15.07.2019" }, { "r030":978,"txt":"\u0404\u0432\u0440\u043e","rate":28.98838500000000095724317361600697040557861328125,"cc":"EUR","exchangedate":"15.07.2019" } ] Было в одну строку, я для читаемости сделал переносы и табы. При первом обновлении получается такой код. При следующих обновах опять всё стирается и записывается null Можно это как то исправить?
Вот, вполне рабочий код PHP: $json = @file_get_contents("https://bank.gov.ua/NBUStatService/v1/statdirectory/exchange?json"); if (!empty($json)) { $kurs_new = json_decode($json); $cron_curs = file_get_contents( __DIR__.'/kursNBU.json'); $kurs_old = json_decode($cron_curs); foreach ($kurs_new as $cur) { foreach ($kurs_old as $item) { if ($item->r030 == $cur->r030) { $item->rate = $cur->rate; $item->exchangedate = $cur->exchangedate; } } } $json_new = json_encode($kurs_old); file_put_contents(__DIR__.'/kursNBU.json', $json_new, LOCK_EX); }
Спасибо! Поставил ваш код. Для теста json отредактировал так: Код (Text): [ { "r030":643,"txt":"Російський рубль","rate":1,"cc":"RUB","exchangedate":"15.07.2017" }, { "r030":840,"txt":"Долар США","rate":1,"cc":"USD","exchangedate":"15.07.2017" }, { "r030":933,"txt":"Бiлоруський рубль","rate":1,"cc":"BYN","exchangedate":"15.07.2017" }, { "r030":978,"txt":"Євро","rate":1,"cc":"EUR","exchangedate":"15.07.2017" } ] После запуска задачи вот что получилось: Код (Text): [{"r030":643,"txt":"\u0420\u043e\u0441\u0456\u0439\u0441\u044c\u043a\u0438\u0439 \u0440\u0443\u0431\u043b\u044c","rate":0.408770000000000022222224060897133313119411468505859375,"cc":"RUB","exchangedate":"15.07.2019"},{"r030":840,"txt":"\u0414\u043e\u043b\u0430\u0440 \u0421\u0428\u0410","rate":25.76058400000000148111212183721363544464111328125,"cc":"USD","exchangedate":"15.07.2019"},{"r030":933,"txt":"\u0411i\u043b\u043e\u0440\u0443\u0441\u044c\u043a\u0438\u0439 \u0440\u0443\u0431\u043b\u044c","rate":12.663740000000000662794263917021453380584716796875,"cc":"BYN","exchangedate":"15.07.2019"},{"r030":978,"txt":"\u0404\u0432\u0440\u043e","rate":28.98838500000000095724317361600697040557861328125,"cc":"EUR","exchangedate":"15.07.2019"}] Ломаются значения для ключей "txt" и что самое важное, для "rate". Так как "txt" в скрипте не трогается, то наверное где то в процессе кодирования-декодирования такое вылазит. Почему так? Есть ли рецепт как такое вылечить?
В самом начале скрипта укажите кодировку PHP: header('Content-Type: text/html; charset=UTF-8'); и замените строку PHP: $json_new = json_encode($kurs_old, JSON_UNESCAPED_UNICODE); rate у меня записывается корректно. Я так понимаю, что данная проблема связана со значением serialize_precision в конфигах https://www.php.net/manual/ru/function.json-encode.php Как вариант, можете просто приводить rate к строковому типу PHP: $item->rate = (string) $cur->rate;
Спасибо! Ваш рецепт помог. Теперь значение в ключе "txt" правильное, а значение ключа "rate" стало строковым типом данных, но само значение правильное. Подскажите пожалуйста, а может это быть связано с настройкой php на хостинге? Я смотрю, у меня на хостинге в разделе php есть вот такая настройка: Это оно?
У меня в настройках хостинга есть раздел "Настройка сайта". Там указана кодировка UTF-8. Убрал из скрипта: PHP: header('Content-Type: text/html; charset=UTF-8'); Задача отрабатывает не ломая значения ключа "txt" Эту часть рецепта решения проблемы оставил: PHP: $json_new = json_encode($kurs_old, JSON_UNESCAPED_UNICODE); и Код (Text): $item->rate = (string) $cur->rate;