Как стать автором
Поиск
Написать публикацию
Обновить

Комментарии 68

nothing, just think aloud...
Второй вариант не работает. Если первай case найден, то остальные выполняются игнорируя case, до breakа.

Иначе,

switch ($x)
{
case 1:
echo 1;
case 2:
echo 2;
case 3:
echo 3;
}

Выведет 123, если икс=1.
Вообще, я пробелами делал выравнивание. Думал, <code> их не вырежет. ^_^

В любом случае, я не вижу выигрыша перед

$errors = array();
if (!is_numeric($phone)) $errors[] = 'badphone';
if (!is_email($email)) $errors[] = 'email';
if (!foo($bar)) $errors[] = 'quux';

if (!empty($errors)) boo();
Действительно...
Пожалуй, уберу эту часть вообще...
Программисты, млин... :)
А break за тебя кто будет ставить? Мама?
switch ($x)
{
case 1:
echo 1; break;
case 2:
echo 2; break;
case 3:
echo 3; break;
}
Если бы вы прочитали, что я написал, поняли бы, что я как раз и указывал на ошибку в коде, который написал автор статьи.
Легче написать статичный класс для валидации данных.
Проверка полей, прослешивание и т.д. осуществляется у меня набором простых функций. Например:
validator::text($param, 1). Первый параметр является строкой или массивом строк. Второй (необязательный) проверяет допустимость пустого значения (0 - может быть пустым, 1 - поле является обязательным). Так же для всех остальных типов. Если, допустим, мне надо проверить правильность заполения поля Emial, то выполняется то просто:

if ($email = validator::email($email, 1)) {
     //выполяняем нужные нам действия
} else {
     // Выводим сообщение об ошибке
}
аха, фреймворки рулят
из статьи можно вынести только интересный switch
валидация и классы уже давно обогнали описываемое

по теме - я использую модели данных, которые позволяют автоматически и формы строить, и данные фильтровать, и отношения строить
неверно располагаете блоки алгоритма
так имхо лучше:

$error_flag = true;
switch (true)
{
  case($_chck->field_empty('name')):
    $error_text = 'Вы не заполнили поле Имя.';
    break;
  case($_chck->field_numeric('age')):
    $error_text = 'Вы не заполнили, или неправильно заполнили поле Возраст.';
    break;
  default:
    $error_flag = false;
    $error_text = NULL;
}

если уж использовать switch, то по полной...
а вообще хорошая замена ifelse'ам, спасибо
А разве при таком подходе мы не получим ситуацию, что когда пользователь ошибся одновременно в нескольких полях, то ему выведется уведомление об ошибке только в том поле, которое в блоке проверок будет идти первым? И дальше по кругу, заставив пользователя по одной отловить все ошибки в форме?
Да, именно так и задумано.
Чтобы получить все ошибки, можно использовать такой подход...
Просто мне казалось, что с точки зрения удобства валидации для конечного пользователя, было бы неплохо сообщать ему обо всех ошибках сразу?
НЛО прилетело и опубликовало эту надпись здесь
Это зависит от конкретного проекта.
НЛО прилетело и опубликовало эту надпись здесь
Если не сложно, примеры таких проектов?
Например, если ошибки выводятся в модальном окне.
Только наверное речь идет о выводе предупреждений в процессе заполнения конкретного поля (а не о финальное проверке валидности)?
Тут, опять же, вопрос выбора конкретного программиста. Можно вызывать скрипт в процессе заполнения, но тогда нельзя будет проверять заполненность полей, а только соответствие данных (т.к. на момент заполнения поля a, поля b, c, d, ... точно еще не заполнены). А можно вызывать скрипт при сабмите формы, тогда если что-то заполнено не так, выдается модальное окно и пользователь остается исправлять данные.
НЛО прилетело и опубликовало эту надпись здесь
Да пишите хоть на Хаскле, меня это совершенно не волнует.
Я предложил лишь одно решение, которое мне кажется достаточно изящным, чтобы иметь право на жизнь.
Использовать, или нет — это личное дело каждого, я никому ничего не навязываю. А вот вы лезете со своим уставом в чужой монастырь...
НЛО прилетело и опубликовало эту надпись здесь
Вы говорите, как вы бы стали решать такую вещь.
Это две большие разницы.
НЛО прилетело и опубликовало эту надпись здесь
По-моему не здорово заставлять пользователя 5-6 раз закрывать модальное окно с единственным сообщением об ошибке. А на сложных формах это будет выглядеть откровенным издевательством.
НЛО прилетело и опубликовало эту надпись здесь
Идите и пишете в блог о .NET.
Может и так, но о велосипедах человек правильно сказал. Только это уже не от языка зависит, а от познаний программиста.
НЛО прилетело и опубликовало эту надпись здесь
Не нравится - не читайте, зачем в каждом топике хаять все на чем свет стоит.
Потому что кто-то из начинающих может принять это (содержимое топика) "за чистую монету", за best practice.
Они наверняка почитают обсуждение тоже.
Для этого здесь и оставлен коммент, не правда ли?
Так кто вам мешает создать рядом топик, в котором вы сможете высказать вашу точку зрения на этот вопрос, помогая начинающему пользователю найти действительно чистую монету!?
Готов поспорить, что найдется масса "профессионалов", которые испачкают ваш best practice...
Я не понимаю, Вы на что обиделись-то? На то, что ваше решение критикуют? Что оно кому-то не нравится?
А кто вам сказал, что я обиделся? (:
Я всего лишь, здесь, как и вы, отстаиваю свою точку зрения...
Мне показалось, что Вы како-то очень болезненно восприняли критику в адрес вашего примера. "Создайте другой топик рядом", "со своим уставом в чужой монастырь". Рад, если это не так.
А я всегда думал, что ф-ция field_empty выглядит примерно так:
public function isEmpty($field)
{
return (!isset($this->data[$field]) || strlen(trim($this->data[$field])) == 0);
}
Велосипед?
http://php.net/empty
Акваланг?
Логику исходной функции автора я не трогал, потому что это не главное здесь.

Про empty я знаю, спасибо.
Простите, не хотел обидеть. ,)

Просто иногда банальные функции из головы вылетают, думал, мало ли. :)
Я тоже был резок, пожалуй :)
empty() не выловит, например, введенный пробел, а для приведенного поля это будет ошибкой
Это уже сугубо личное дело каждого. Когда таких функция сотня, все-таки хочется, чтобы они были более читаемыми...
Если честно, то я не понимаю, как семь лишних, ничего не делающих строчек, могут повысить читаемость кода. Хотя, вы, разумеется, правы — хозяин барин.
Может стоит вместо switch использовать полиморфизм: код будет понятней и легко расширяемый + не будет дублирования, если проверок несколько.
Очень красиво.
В конструкторе можно воткнуть
foreach($a as &$value) {
   $value=trim($value);
}
Ваша конструкция работает только в PHP >= 5.

В любом случае, есть лучшее решение:

$a = array_map('trim', $a);
Согласен.
НЛО прилетело и опубликовало эту надпись здесь
Согласен. Я взял этот пример с php.net.
У меня опять глупый вопрос.
В чем разница (с точки зрения PHP) между конструкцией
if (func1($a)) {...}
elseif (func2($a)) {...}
elseif (func3($a)) {...}

и такой:
switch(true)
{
case (func1($a)):
...;
break;
case (func2($a)):
...;
break;
case (func3($a)):
...;
break;
}

Не с точки зрения синтаксиса, а с т.з. отработки интерпретатором.
Трудно дать точный ответ... Лично я не нашел четкого описания такого подхода, встречал только примеры в комментариях... Но, я предполагаю, что ровным счетом никакой разницы нет...
Разница есть между:
<?php
if (myFunc($x) == 1)
{
echo 1;
}
elseif (myFunc($x) == 2)
{
echo 2;
}
elseif (myFunc($x) == 3)
{
echo 3;
}
else
{
echo 4;
}
?>
и
<?php
switch (myFunc($x))
{
case(1):
echo 1;
break;
case(2):
echo 2;
break;
case(3):
echo 3;
break;
default:
echo 4;
break;
}
?>

Тогда, в первом случае функция myFunc() (возможно) будет вызвана 3 раза, тогда как во втором случае только 1 раз.
Собственно, в этом и состоит основной смысл оператора switch().
Ну за первый вариант я бы вообще отбирал клавиатуру и отправлял учиться на юриста (no offence).
Возвращаясь к исходным примерам (в моём комменте), по-моему разницы никакой нет, а вариант с elseif'ами читается (тут ИМХО, конечно) не в пример лучше.
К тому же конструкция switch(true) - это вообще что-то по ту сторону добра и зла.
Да уж, так в жизни заведено: все самое интересное всегда по ту сторону добра и зла (:
Да ну, что в этой конструкции интересного-то? :) В практическом плане, а не в "перловом" ;)
Интересно то, кто когда спрашивают "как сделать несколько проверок" большинство отвечает "elseif"...
Можно сказать "нестандартный, но верный" подход...
большинство отвечает "elseif"...

Большинство отвечает решительно верно :)
Можно сказать "нестандартный, но верный" подход...

Верный только в том смысле, что работает :) С такой формулировкой соглашусь.
НЛО прилетело и опубликовало эту надпись здесь
Я могу ошибаться, но по-моему, по скорости они совершенно идентичны (т.к. одни и те же операции совершаются).
Скорость зависит от расположения проверок, например, если мы знаем, что наибольшая вероятность, что пользователь не заполнил какое-то поле, то нужно эту проверку поставить как можно выше (как в switch, так и в elseif конструкции). Хотя, разница в скорости будет настолько ничтожно мала, что этим вполне можно пренебречь.
ЕМНИП, switch раскладывается в дерево, что немного более ресурсозатратно elseif'ов, которые выполняются "в порядке поступления" и, конечно, не является идентичным.
Но пока что мне решение понравилось и уже довелось использовать;)
чОрт
Тысяча извинений, способ непригоден.
Switch действительно разворачивается в дерево - находятся значения всех case'ов, после чего switch проходит по этому дереву, ища совпадения.
Соответственно, у нас получается значительное замедление, плюс нежелательные вызовы. Ситуация должна быть редкой, чтобы затмить эти минусы. И уж точно этот способ не подходит для цепочки условий, в которой первое же нарушение должно прерывать выполнение.

"Эх..." сказали суровые сибирские мужики и пошли дальше писать elseif'ами
Вы меня прямо заинтриговали фразой «разворачивается в дерево». Даже мой воспаленный мозг не может представить, как это (:

Вот небольшой бенчмарк (если можно так сказать) для сравнения скорости работы двух методов:
<?php
function getmicrotime()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}

function check1()
{
sleep(1);
return false;
}

function check2()
{
sleep(2);
return false;
}

function check3()
{
sleep(3);
return true;
}

function check4()
{
sleep(4);
return false;
}

/* ============ */

$ie_time_start = getmicrotime();

if (check1())
{
echo '1';
}
elseif (check2())
{
echo '2';
}
elseif (check3())
{
echo '3';
}
elseif (check4())
{
echo '4';
}

$ie_time = getmicrotime() - $ie_time_start;

/* ============ */

$sw_time_start = getmicrotime();

switch (true)
{
case(check1()):
echo '1';
break;
case(check2()):
echo '2';
break;
case(check3()):
echo '3';
break;
case(check4()):
echo '4';
break;
}

$sw_time = getmicrotime() - $sw_time_start;

/* ============ */

echo '<hr />';
echo 'ElseIf has taken ' . round($ie_time, 4);
echo '<br />';
echo 'Switch has taken ' . round($sw_time, 4);
?>
Можете попробовать сами, но у меня этот скрипт выводит:
ElseIf has taken 5.9997
Switch has taken 6.0001
Хотя, по вашей древесной теории switch в данном случае должен занимать никак не меньше 10 секунд, «проходя по всему дереву, ища совпадения»...
Более того, запустив скрипт более 3 раз можно увидеть, что зачастую switch отрабатывает быстрее, нежели elseif, но это уже причуды интерпретатора...
Предлагаю все-таки остановиться на предыдущем утверждении: «по скорости они совершенно идентичны (т.к. одни и те же операции совершаются)»
Разницы никакой. К elseif народ привычнее, нужно всегда помнить о человеке, которому возможно ваш код перейдет в наследство.
Угу, именно.
Лично я бы на строчке switch(true) при просмотре кода запнулся бы и вместо того, чтобы разобираться с сутью программы, начал бы анализировать, как оно работает.
Начинаешь в мозгу невольно бегать по строчкам как интерпретатор. Вообщем не есть гуд.
НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации