Image

Listens: Иванушки Int - Тучи

Categories:

Так уж выходит, что по работе мне мало приходится программировать, но в сутках 24 часа, из них работаю я 8, сплю где-то 10, так что у меня ещё остаётся время :) Ни семьи, ни жены, ни девушки у меня нет, второй работы или какой-то подработки тоже не имеется. А из-за моего неумелого планирования финансов иногда так выходит, что и денег тоже не остаётся.

Я не лажу по горам, не бегаю с фотоаппаратом, не езжу по заграницам, и даже не Алтае не был. Чем же я занимаюсь?

Часть времени я общаюсь. Общаюсь в интернете, общаюсь с друзьями, встречаюсь и стараюсь хоть как-нибудь оторваться от компьютера. Есть время когда я смотрю что-нибудь, в кино или за компьютером, например, сейчас я смотрю весь сериал «Скользящие»

А ещё одно любимое занятие — программирование!! Да-да, мне нравится программировать, особенно когда это у меня получается.

В последнее время я пописываю на РНР :) Разбираюсь с Zend Framework'ом и потихонечку делаю сайт. Делаю неторопясь, делаю хорошо, на совесть и для себя.

Сегодня я впервые за всё время нашел применение логической операции XOR! Мне пришлось немного порыться в википедии, чтобы найти таблицы истинности для неё и увериться, что она подходит для моей задачи. Подошла!

Вкратце, для тех не не знает или забыл напоминаю: xor (или исключающее ИЛИ) возвращает истину когда только один из аргументов истинен, а второй нет. Т.е. если оба истинны или оба ложны, то возращается false.

А задача была следующая. Есть форма, с тремя полями для ввода. Название страны, ссылка на её описание, это два обязательных поля. Также есть два необязательных, для перевода — название страны на русском языке и ссылка на русскоязычное описание.

Два поля являются опциональными, но если уж пользователь их выбрал, то заполнять требуется оба (таковы условия)! Именно здесь-то операция xor и пригодилась. Ниже я приведу пример кода на РНР, для иллюстрации того, как это можно проверить.

Маленькое отступление. Я хотел и несколько раз порывался написать про Zend Framework, но всё никак не хватало меня. В кусочке кода ниже, кстати, демонстрируется новая фишка из ещё пока не стабильного Zend Framework 1.6.0: программист может вмешаться в стандартный ход проверки полей формы на валидность.

Казалось бы, есть Zend_Validate, который легко прикручивается к Zend_Form, но есть случаи, и они не так уж редки, когда проверка должна быть несколько выше и касаться не одного поля, а нескольких. Например, пароль и его подтверждение — нужно проверить, что значение в двух полях идентичны. Или в задаче, которую я привёл выше — нужно выдать ошибку, если из двух опциональных полей одно незаполнено.

Вот мой код (к сожалению я не знаю как бы его раскрасить):


if ($this->getRequest()->isPost()) {

    if ($form->isValid($this->getRequest()->getPost())) {

        $values = $form->getValues();
        $t_name_empty = empty($values['country_name_l10n']);
        $t_url_empty  = empty($values['country_url_l10n']);

        // When user supply only translated country name or only
        // country url but not a both
        if ($t_name_empty xor $t_url_empty) {

            // determine what field leave empty
            $empty_field_name = ($t_name_empty ? 'country_name_l10n' : 'country_url_l10n');

            // find this field and mark as failed validation
            foreach ($form->getElements() as $element) {
                if ($element->getName() === $empty_field_name) {
                    // addError() function appears in ZF since
                    // 1.6.0RC1
                    $element->addError('isEmpty');
                }
            }

         } else {
             $this->addCountry($values);
         }
     }
}



P.S. Обилие закрывающих скобочек мне не нравится, но после этого есть ещё код и вставить return я не могу. Что ж, может потом код изменится сам или я его как-то отрефакторю и он будет более опрятным.

P.P.S. А ещё Zend довольно прожорлив и мне пришлось повысить memory_limit c 5 Мб до 8 (очень не хотелось, но пришлось).

Updated(20100123):: НЕ НАДО проверять значения в контроллере, как я это пытался делать тогда, когда писался этот пост. Правильным способом является написание собственного валидатора.