Просмотр поста

.
Delphinum
Валидатор
Процесс фильтрации и валидации данных очень важен для безопасности системы. Ни для кого не секрет, что поступающие в систему данные должны проверяться прежде чем они будут обработаны. Лично я использую "контрактный подход" внутри системы, и проверку входящих в нее данных. Другими словами, все что приходит в систему из вне проверяется, а внутри системы данные передаются уже в проверенном и безопасном виде.

Чаще всего Web-приложения оперируют с пакетами, содержащими несколько именованных данных, на пример такими:

$_POST = [
  'id' => '123',
  'message' => 'Тестовое сообщение в чате',
  'author_id' => '1',
];


Обрабатываться данные в пакете должны в соответствии с некоторой "картой валидации". К примеру идентификатор (id) должен быть сначала приведен к целочисленному типу, а затем проверен на вхождение в диапазон (значение должно быть больше нуля). Это можно сделать так:

$id = (int) $_POST['id'];
if($id <= 0){
  die('Недопустимые данные');
}


Этого достаточно для обеспечения безопасности системы, но проверять все данные из всех пакетов становится довольно накладно. Более того, обычно для проверки применяются одинаковые механизмы, но в разной последовательности. Этот набор механизмов проверки и называется "картой валидации".

Пакет Bricks.Validation облегчает и унифицирует процесс проверки пакетов данных сводя его к определению "карты валидации" для конкретного пакета.

Прежде чем начать использовать этот пакет, необходимо научиться различать "Валидатор" и "Фильтр":

Фильтр - механизм изменяющий данные и приводящий их к некоторому виду (на пример приведение к целому типу или trim по строке). Фильтр не проверяет данные, а только подготавливает их
Валидатор - механизм проверяющий данные на предмет нахождения в них недопустимых значений (на пример отрицательных чисел или слишком длинных строк)

Предложенный мной пакет реализует несколько готовых классов фильтрации и валидации данных, позволяющих обрабатывать большинство пакетов данных, используемых в Web-приложениях. Рассмотрим некоторые из них:

Фильтры
Int, String - приведение к целочисленному значению или к строке
Trim - обрезка строки с начала и конца
IntRange, StringRange - приведение числа или длины строки к указанному диапазону
Path - выделение компонента из адреса файлового ресурса (на пример имени файла или расширения)
Url - выделение компонента из URL адреса (на пример порта или хоста)
Валидаторы
NoEmpty - не пустые данные
Length - проверка длины данных
Regex - проверка строки с помощью регулярного выражения
Email - проверка email на корректность
Ip - проверка IP адреса на корректность
Url - проверка Url на корректность

Вы можете создавать свои фильтры и валидаторы и использовать их для пакетной валидации данных в своих приложениях.

Пакетная валидация выполняется с помощью класса Input данного пакета. При инстанциации этого класса конструктору необходимо передать "карту валидации", которая будет применяться объектом к проверяемым данным. Карта представляется в виде ассоциативного массива, фильтры в котором указываются с ведущим знаком !, а валидаторы со знаком ?. Порядок перечисления очень важен, так как именно в этом порядке они будут применяться к данным.

Пример карты валидации:

use Bricks\Validation\Input;

$input = new Input([
  'id' => ['!int', '?length', 'min' => 1],
  'message' => ['!string', '?length', 'max' => 256],
  'author_id' => ['!int', '?length', 'min' => 1],
]);


Разберем этот пример. Данная "карта валидации" определяет следующие правила:
Для id - сначала приведение данных к целочисленному типу с помощью фильтра Int, затем валидация полученных данных с помощью валидатора Length дабы число было больше или равно 1
Для message - сначала приведение данных к строковому типу с помощью фильтра String, затем валидация полученных данных с помощью валидатора Lenght, дабы длина строки не превышала 256 символов
author_id обрабатывается аналогично id

Когда пакетный обработчик создан, с помощью метода validate ему можно передать массив данных, которые он проверит и вернет подготовленный (безопасный) пакет или выбросит исключение, если данные не безопасны:

...
$data = $input->validate($_POST);


Довольно просто, не правда ли? Суть этого метода заключается в применении таких "карт валидации", которые позволят максимально гибко и безопасно обработать данные. Рассмотрим еще один пример более сложной валидации:

use Bricks\Validation\Input;

$input = new Input([
  'message' => ['!string', '!trim', '?length', 'min' => 1, 'max' => 256],
  'from' => ['!string', '!trim', '?email'],
  'file' => ['!string', '!trim', '!path', 'path' => 'basename', '?length', 'min' => 1],
]);


Архив с примером.