# Введение

Компонента Zend_Validate предоставляет набор наиболее часто используемых валидаторов. Она также предоставляет простой механизм формирования цепочки валидаторов, посредством которого к одним и тем же данным может быть применено несколько валидаторов в порядке, заданном пользователем.

## Что такое валидатор?

Валидатор проверяет входные данные на предмет соответствия требованиям и возвращает результат булевого типа. Если входные данные не соответствуют требованиям, то валидатор может предоставить информацию о том, какому требованию (требованиям) не соответствуют входные данные.

Например, веб-приложение может требовать, чтобы имя пользователя было длиной от 6 до 12 символов и содержало только алфавитно-цифровые символы. Для того, чтобы проверить, соответствует ли имя пользователя этим требованиям, можно использовать валидатор. Если выбранное имя пользователя не соответствует одному из требований (или обоим требованиям), то будет также полезно знать, каким именно требованиям не соответствует имя пользователя.

## Базовое использование валидаторов

Такое определение валидации дает основу для Zend_Validate_Interface, который определяет два метода - `isValid()` и `getMessages()`. Метод `isValid()` выполняет валидацию переданного значения, возвращая `TRUE` тогда и только тогда, когда значение прошло проверку по критериям валидации.

Если `isValid()` возвращает `FALSE`, то `getMessages()` возвращает массив сообщений, поясняющих, по каким причинам валидация не была пройдена. Ключи массива являются короткими строками, идентифицирующими причины, по которым не была пройдена валидация. Значения массива являются строками сообщений, понятных человеку. Ключи и значения зависят от класса валидатора - каждый класс валидатора определяет собственный набор сообщений об ошибке и уникальных ключей-идентификаторов. Каждый класс также определяет константы, соответствующие идентификаторам причин, по которым валидация не была пройдена.

Метод `getMessages()` возвращает сообщения ошибок валидации только для последнего вызова `isValid()`. Любой вызов метода `isValid()` стирает все сообщения и ошибки с его прошлого вызова, т.к. вероятно, что отдельные вызовы `isValid()` производятся для различных входных значений.

Следующий пример демонстрирует проверку адреса e-mail:

    $validator = new Zend_Validate_EmailAddress();

    if ($validator->isValid($email)) {
        // email прошел валидацию
    } else {
        // email не прошел валидацию; вывод причин этого
        foreach ($validator->getMessages() as $messageId => $message) {
            echo "Validation failure '$messageId': $message\n";
        }
    }

## Установка собственных сообщений от ошибках

Классы валидации предоставляют метод `setMessage()`, с помощью которого вы можете устанавливать формат сообщения, возвращаемого методом `getMessages()` в случае, если валидация не была пройдена. Первый аргумент этого метода является строкой, содержащей текст сообщения об ошибке. Вы можете включать в нее маркеры, которые будут замещаться данными, относящимися к валидатору. Маркер `%value%` поддерживается всеми валидаторами, он заменяется значением, который вы передали методу `isValid()`. Другие маркеры могут поддерживаться не во всех валидаторах. Например, `%max%` является маркером, поддерживаемым валидатором Zend_Validate_LessThan. Метод `getMessageVariables()` возвращает массив маркеров, поддерживаемых валидатором.

Второй необязательный аргумент является строкой, которую нужно установить в качестве идентификатора шаблона сообщения, это может быть полезным в том случае, когда класс валидации предусматривает несколько причин, по которым валидация может быть не пройдена. Если вы опустите второй аргумент, то `setMessage()` предполагает, что переданное вами сообщение должно использоваться в качестве первого шаблона сообщения, объявленного в классе валидации. Многие классы валидации имеют только один шаблон сообщения об ошибке, поэтому в большинстве случаев нет необходимости указывать, какой именно шаблон требуется изменить.

    $validator = new Zend_Validate_StringLength(8);

    $validator->setMessage(
        'Строка \'%value%\' слишком короткая. Она должна быть длиной как минимум ' .
        '%min% символов',
        Zend_Validate_StringLength::TOO_SHORT);

    if (!$validator->isValid('слово')) {
        $messages = $validator->getMessages();
        echo current($messages);

        // "Строка 'слово' слишком короткая. Она должна быть длиной как минимум
        // 8 символов"
    }

Вы можете устанавливать несколько сообщений сразу, используя метод `setMessages()`. Его аргумент является массивом, содержащим пары ключ/значение.

    $validator = new Zend_Validate_StringLength(8, 12);

    $validator->setMessages( array(
        Zend_Validate_StringLength::TOO_SHORT =>
            'Строка \'%value%\' слишком короткая',
        Zend_Validate_StringLength::TOO_LONG  =>
            'Строка \'%value%\' слишком длинная'
    ));

Если ваше приложение требует большей гибкости, ... то вы можете использовать доступ к свойствам под теми же именами, что и метки сообщения, поддерживаемые данным классом валидации. Свойство `value` всегда доступно в валидаторах, это значение, которое вы передали в качестве аргумента метода `isValid()`. Другие свойства могут поддерживаться не всеми классами валидации.

    $validator = new Zend_Validate_StringLength(8, 12);

    if (!validator->isValid('слово')) {
        echo 'Слово не прошедшее проверку: '
            . $validator->value
            . '; его длина не находится в диапазоне между '
            . $validator->min
            . ' и '
            . $validator->max
            . " символами\n";
    }

## Использование статического метода is()

Если неудобно каждый раз загружать требуемый класс валидации и создавать его экземпляр, то можно использовать статический метод `Zend_Validate::is()` в качестве альтернативного способа вызова. Первый аргумент этого метода является входным значением, которое вы передавали бы методу `isValid()`. Второй аргумент является строкой, которая соответствует базовому имени класса валидации относительно пространства имен `Zend_Validate`. Метод `is()` автоматически загружает класс, создает его экземпляр и применяет метод `isValid()` к входным данным.

    if (Zend_Validate::is($email, 'EmailAddress')) {
        // Да, похоже, email валиден
    }

Вы можете также передавать массив аргументов конструктора, если они нужны для данного класса валидации.

    if (Zend_Validate::is($value, 'Between', array(1, 12))) {
        // Да, $value имеет значение в диапазоне между 1 и 12
    }

Метод `is()` возвращает значение булевого типа, как и метод `isValid()`. При использовании статического метода `is()` сообщения ошибки валидации не доступны.

Вариант со статическим методом может быть удобным при единичном вызове валидатора, но если вам нужно применить валидацию к нескольким входным значениям, то более эффективным будет использование варианта с инстанцированием.

Кроме того, класс Zend_Filter_Input позволяет инстанцировать и запускать более одного класса фильтра и валидации для обработки набора входных данных. Читайте .

## Перевод сообщений

Классы валидации предоставляют метод `setTranslator()`, с помощью которого вы можете устанавливать экземпляр класса Zend_Translate, который будет переводить сообщения в случае ошибки валидации. Метод `getTranslator()` возвращает установленный экземпляр переводчика.

    $validator = new Zend_Validate_StringLength(8, 12);
    $translate = new Zend_Translate(
        'array',
        array(Zend_Validate_StringLength::TOO_SHORT => 'Translated \'%value%\''),
        'en'
    );

    $validator->setTranslator($translate);

С помощью статического метода `setDefaultTranslator()` вы можете установить экземпляр Zend_Translate, который будет использоваться во всех классах валидации, и извлекать его с помощью `getDefaultTranslator()`. Это избавляет от установки вручную переводчика для всех классов валидации и упрощает ваш код.

    $translate = new Zend_Translate(
        'array',
        array(Zend_Validate_StringLength::TOO_SHORT => 'Translated \'%value%\''),
        'en'
    );
    Zend_Validate::setDefaultTranslator($translate);

Если вы установили глобальную для всего приложения локаль через Zend_Registry, то эта локаль будет использоваться по умолчанию в переводчике.

Иногда бывает необходимым отключить переводчика в валидаторе. Для этого используйте метод `setDisableTranslator()`, который принимает булево значение. Для получения установленного значения используйте `translatorIsDisabled()`.

    $validator = new Zend_Validate_StringLength(8, 12);
    if (!$validator->isTranslatorDisabled()) {
        $validator->setDisableTranslator();
    }

Вы можете также использовать переводчика вместо установки собственных сообщений через метод `setMessage()`. Но при этом имейте в виду, что переводчик обрабатывает и сообщения, которые вы установили самостоятельно.