У навчальній інтеграції магазин отримує відповідь постачальника, але замість очікуваного статусу бачить порожнє значення. Розробник додає запасний результат «немає товару», і пошкоджена відповідь непомітно перетворюється на бізнес-рішення. Помилки JSON у PHP варто відокремлювати від коректних даних: тоді збій обміну не маскується під відсутність запису. Розглянемо це на невеликому локальному прикладі без звернень до сторонніх сервісів.
Мета — розрізняти три ситуації: документ не вдалося декодувати, документ прочитано, але його структура не відповідає домовленості, або структура правильна й можна продовжувати роботу. Це різні причини та різні наступні дії. Приклад не змінює каталог, не проводить платежі й не реалізує повноцінний клієнт API. Його можна використати як основу окремого тесту перед змінами в інтеграції.
Спочатку встановіть межу між транспортом і даними
У реальному обміні до декодування перевіряють, чи запит узагалі завершився, який отримано HTTP-статус і який тип вмісту повернув сервер. Сторінка помилки проксі може містити HTML навіть там, де очікувався JSON. Не намагайтеся виправити її пошуком фігурних дужок у тексті: потрібно дослідити причину відповіді, а не випадково витягнути схожий на документ фрагмент.
Зберігайте окремі ознаки помилки з’єднання та помилки декодування. Наприклад, діагностичне повідомлення може містити назву операції, статус відповіді та внутрішній ідентифікатор запиту. Повний вміст відповіді не слід автоматично записувати до загального журналу: там можуть бути адреси, токени або інші приватні дані. Доступ до журналів і строк їх зберігання також потребують продуманих правил.
Для нашого тесту джерело вже відоме: це звичайний рядок, заданий у файлі. Отже, мережеві перевірки тут свідомо відсутні. У продуктивному коді додайте їх перед цим фрагментом відповідно до бібліотеки, якою виконуєте запит. Не переносіть навчальне спрощення на робочу інтеграцію й не робіть повторну відправку замовлення лише тому, що відповідь виявилася нечитабельною.
Зробіть помилку декодування явною
В офіційному довіднику PHP описані json_decode та JsonException. Прапорець JSON_THROW_ON_ERROR з’явився у PHP 7.3; це межа доступності можливості, а не рекомендація використовувати стару версію. Для вправи потрібен підтримуваний PHP із цією можливістю та доступ до локального термінала. Адміністративні права, додаткові пакети й доступ до бази даних не потрібні.
Створіть новий файл json-demo.php у тестовому каталозі. Не використовуйте ім’я чинного файла інтеграції, щоб випадково не перезаписати його. Наведений код розрахований на звичайний файл без оголошеного namespace; у просторі імен застосуйте імпорт JsonException або повністю кваліфіковану назву. Рядок raw та значення status умовні: замініть їх відповідно до власного контракту відповіді.
<?php
$raw = '{"status":"ready"}';
try {
$data = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
} catch (JsonException $e) {
echo "Invalid JSON", PHP_EOL;
exit(1);
}
if (!is_array($data) || !isset($data['status'])
|| !is_string($data['status'])) {
echo "Unexpected structure", PHP_EOL;
exit(1);
}
echo "Accepted", PHP_EOL;
Прапорець переводить помилку декодування в явний виняток, який цей приклад перехоплює. Успішне декодування саме по собі ще не гарантує потрібних полів: тому після нього перевіряються тип результату, наявність status і тип цього значення. Другий аргумент true обирає асоціативні масиви для об’єктів JSON. Повідомлення виводяться лише для локальної вправи, а не для відвідувача робочого сайту.
Запустіть перевірку синтаксису та сам тест із каталогу, де збережено новий файл. Перша команда не перевіряє бізнес-логіку, тому потрібна й друга. Якщо php не знайдено, використайте налаштований термінал середовища розробки або уточніть шлях до свого інтерпретатора. Не встановлюйте випадкові пакети лише для того, щоб команда почала виконуватися.
php -l json-demo.php
php json-demo.php
Зберіть набір випадків, які не можна плутати
Для початкового документа очікується гілка «Accepted». Потім по черзі змінюйте лише рядок raw: приберіть закривальну дужку, передайте JSON зі status у вигляді числа, задайте порожній об’єкт і окремо рядок null. Пошкоджений документ має потрапити до гілки декодування, а коректні, але непридатні структури — до «Unexpected structure». Це очікування тесту, не звіт про виконання на вашому сервері.
Особливо важливий коректний JSON null. Без явної обробки помилки значення null може означати як дані документа, так і невдале декодування. Не використовуйте лише порівняння результату з null як універсальний детектор помилки. Так само порожній масив, порожній об’єкт і відсутність потрібного поля не повинні автоматично означати успішний результат операції.
Наш контракт перевіряє тільки рядковий status. У справжній інтеграції потрібно також обмежити дозволені значення, перевірити обов’язкові ідентифікатори й типи вкладених полів. Наприклад, незнайомий статус не варто трактувати як підтверджене замовлення. Визначте окрему поведінку для нових значень, щоб зміна контракту постачальника не запускала випадкову дію в магазині.
Перенесіть правило в інтеграцію без небезпечних підмін
Перед доопрацюванням збережіть робочу версію коду та перевірте Git-коміт. Проведіть вправу на тестовій копії з навчальними відповідями, а не з реальними замовленнями. Додайте тести для правильного документа, пошкодженого синтаксису й неправильного типу поля. У журналі відокремте причину збою від технічної подробиці; зовнішньому користувачу покажіть зрозуміле повідомлення без внутрішніх шляхів або секретів.
Не виправляйте JSON загальною заміною одинарних лапок на подвійні: це може змінити текстові значення. Не підставляйте порожній масив після будь-якого винятку, якщо подальший код сприймає його як нормальні дані. Відновлення має бути явним: призупинити конкретну операцію, запропонувати повторну перевірку або передати випадок для розбору. Спосіб залежить від наслідків операції та її правил повторення.
Висновок: надійність починається не зі складного парсера, а з чіткої межі між пошкодженим документом і неправильним контрактом. Якщо інтеграція поводиться непередбачувано, AriZone може допомогти локалізувати збій і підготувати перевірки до виправлення. Для відкату поверніть попередню версію конкретної зміни, не вимикаючи перевірку даних у всьому застосунку.
Залиште коментар