Schema: валідація даних
Практична бібліотека для перевірки та нормалізації структур даних за заданою схемою з інтелектуальним і простим у розумінні API.
Встановлення:
Використання
У змінній $schema
у нас є схема валідації (що саме це значить і як
її створити, ми розповімо пізніше), а у змінній $data
у нас є
структура даних, яку ми хочемо валідувати та нормалізувати. Це можуть
бути, наприклад, дані, надіслані користувачем через API, конфігураційний
файл тощо.
Завданням займається клас Nette\Schema\Processor, який обробляє вхідні дані та або повертає нормалізовані дані, або викидає виняток Nette\Schema\ValidationException у разі помилки.
Метод $e->getMessages()
повертає масив усіх рядків повідомлень, а
$e->getMessageObjects()
повертає всі повідомлення у вигляді об'єктів Nette\Schema\Message.
Визначення схеми
А тепер давайте створимо схему. За допомогою класу Nette\Schema\Expect ми фактично
визначаємо, як мають виглядати дані. Припустимо, що вхідні дані повинні
являти собою структуру (наприклад, масив), що містить елементи
processRefund
типу bool і refundAmount
типу int.
Ми вважаємо, що визначення схеми виглядає зрозумілим, навіть якщо ви бачите його вперше.
Відправимо такі дані для перевірки:
Вихід, тобто значенням $normalized
, є об'єкт stdClass
. Якщо ми
хочемо, щоб результатом був масив, ми додаємо приведення до схеми
Expect::structure([...])->castTo('array')
.
Усі елементи структури є необов'язковими і мають значення за
замовчуванням null
. Приклад:
Той факт, що значенням за замовчуванням є null
, не означає, що
воно буде прийнято у вхідних даних 'processRefund' => null
. Ні, вхідні
дані повинні бути булевими, тобто тільки true
або false
. Нам
довелося б явно дозволити null
через Expect::bool()->nullable()
.
Елемент можна зробити обов'язковим, використовуючи
Expect::bool()->required()
. Ми змінюємо значення за замовчуванням на
false
, використовуючи Expect::bool()->default(false)
або коротко
Expect::bool(false)
.
А що якщо ми захочемо приймати 1
и 0
крім булевих чисел?
Перелічимо допустимі значення, які ми також нормалізуємо в boolean:
Тепер ви знаєте основи того, як визначається схема і як поводяться окремі елементи структури. Тепер ми покажемо, які ще елементи можуть бути використані при визначенні схеми.
Типи даних: type()
Усі стандартні типи даних PHP можуть бути перераховані в схемі:
А потім всі типи, підтримувані
валідаторами через Expect::type('scalar')
або скорочено
Expect::scalar()
. Також приймаються імена класів або інтерфейсів,
наприклад: Expect::type('AddressEntity')
.
Ви також можете використовувати нотацію об'єднання:
Значення за замовчуванням завжди null
, за винятком array
і
list
, де це порожній масив. (Список – це масив, індексований у
порядку зростання числових ключів від нуля, тобто неасоціативний
масив).
Масив значень: arrayOf() listOf()
Масив – занадто загальна структура, корисніше вказати, які саме елементи він може містити. Наприклад, масив, елементами якого можуть бути тільки рядки:
Другий параметр може використовуватися для вказівки ключів (починаючи з версії 1.2):
Список являє собою індексований масив:
Параметр також може бути схемою, тому ми можемо написати:
Значення за замовчуванням – порожній масив. Якщо ви вкажете
значення за замовчуванням, воно буде об'єднано з переданими даними. Це
можна відключити за допомогою mergeDefaults(false)
(починаючи з
версії 1.1).
Перерахування: anyOf()
anyOf()
– це набір значень або схем, якими може бути значення. Ось
як записати масив елементів, які можуть бути або 'a'
, або
true
, або null
:
Елементи перерахування також можуть бути схемами:
Метод anyOf()
приймає варіанти як окремі параметри, а не як масив.
Щоб передати йому масив значень, використовуйте оператор розпакування
anyOf(...$variants)
.
Значення за замовчуванням – null
. Використовуйте метод
firstIsDefault()
, щоб зробити перший елемент елементом за
замовчуванням:
Структури
Структури – це об'єкти з певними ключами. Кожна з цих пар ключ ⇒ значення називається “властивістю”:
Структури приймають масиви та об'єкти і повертають об'єкти
stdClass
.
За замовчуванням усі властивості є необов'язковими і мають значення
за замовчуванням null
. Ви можете визначити обов'язкові
властивості, використовуючи required()
:
Якщо ви не хочете виводити властивості тільки зі значенням за
замовчуванням, використовуйте skipDefaults()
:
Хоча null
є значенням за замовчуванням властивості optional
,
воно не допускається у вхідних даних (значення має бути рядком).
Властивості, що приймають значення null
, визначаються за
допомогою nullable()
:
Масив усіх властивостей структури повертається методом
getShape()
.
За замовчуванням, у вхідних даних не може бути зайвих елементів:
Подібні елементи змінити за допомогою otherItems()
. Як параметр ми
вкажемо схему для кожного додаткового елемента:
Ви можете створити нову структуру, виводячи її з іншої за допомогою
extend()
:
Масив
Масив з визначеними ключами. Застосовуються ті ж правила, що і для структур.
Ви також можете визначити індексований масив, відомий як кортеж:
Застарілі елементи
Ви можете оголосити властивість застарілою, використовуючи метод
deprecated([string $message])
. Повідомлення про застарівання повертаються за
допомогою $processor->getWarnings()
:
Діапазони: min() max()
Використовуйте min()
і max()
для обмеження кількості
елементів у масивах:
Для рядків обмежує їхню довжину:
Для чисел обмежує їхнє значення:
Звичайно, можна згадати тільки min()
, або тільки max()
:
Регулярні вирази: pattern()
Використовуючи pattern()
, ви можете вказати регулярний вираз,
якому має відповідати всівся вхідний рядок (тобто так, ніби він був
загорнутий у символи ^
a $
):
Користувацькі твердження: assert()
Ви можете додати будь-які інші обмеження, використовуючи
assert(callable $fn)
.
Або
Ви можете додати власний опис для кожного твердження. Він буде частиною повідомлення про помилку.
Метод можна викликати багаторазово, щоб додати кілька обмежень. Його
можна змішувати з викликами transform()
та castTo()
.
Перетворення: transform()
Успішно перевірені дані можна змінити за допомогою спеціальної функції:
Метод можна викликати багаторазово, щоб додати кілька перетворень.
Його можна змішувати з викликами assert()
та castTo()
. Операції
будуть виконані в тому порядку, в якому вони були оголошені:
Метод transform()
може одночасно перетворювати і перевіряти
значення. Часто це простіше і менш надлишково, ніж ланцюжок
transform()
і assert()
. Для цього функція отримує об'єкт Context з методом addError()
,
який можна використовувати для додавання інформації про проблеми з
валідацією:
Кастинг: castTo()
Успішно перевірені дані можуть бути закинуті:
На додаток до власних типів PHP, ви також можете виконувати приведення до класів. При цьому розрізняється, чи це простий клас без конструктора, чи клас з конструктором. Якщо клас не має конструктора, створюється його екземпляр і всі елементи структури записуються в його властивості:
Якщо клас має конструктор, то елементи структури передаються як іменовані параметри до конструктора:
Приведення у поєднанні зі скалярним параметром створює об'єкт і передає значення як єдиний параметр до конструктора:
Нормалізація: before()
Перед самою перевіркою дані можуть бути нормалізовані за допомогою
методу before()
. Як приклад, нехай є елемент, який має бути масивом
рядків (наприклад, ['a', 'b', 'c']
), але отримує вхідні дані у вигляді
рядка a b c
:
Відображення на об'єкти: from()
Ви можете згенерувати схему структури з класу. Приклад:
Також підтримуються анонімні класи:
Оскільки інформації, отриманої з визначення класу, може бути недостатньо, ви можете додати власну схему для елементів за допомогою другого параметра: