LINUX.ORG.RU

Странный checkbox

 ,


0

1

Впервые столкнулся с таким странным поведением:

<form>
<input type=text name=f1 value=sometext>
<input type=checkbox name=f2 checked>
echo var_export($_POST);
Отправляем форму:
array(
  'f1'=>'sometext',
  'f2'=>'1',
)
Отправляем форму, сняв отметку:
array(
  'f1'=>'sometext',
)

При этом ожидается, что f2 будет иметь значение 0, NULL, " или какое-либо еще, но если чекбокс не отмечен, нет _никакого_!

Вопрос, нормально ли это и как с этим бороться?

В контексте моей задачи существует разница между отсутствием отметки в чекбоксе и отсутствием значения.

В контексте моей задачи существует разница между отсутствием отметки в чекбоксе и отсутствием значения.

А почему? В смысле интересно как так вышло.

По теме - php конечно ублюдочный язык, но в данном случае все правильно и php тут вообще не при делах.

gnunixon ★★★
()
Ответ на: комментарий от Kalashnikov

всё нормально

Потому что в учебнике так написано? Допустим. Есть соображения, ка сделать ненормально?

linuxnewb
() автор топика
Ответ на: комментарий от gnunixon

А почему? В смысле интересно как так вышло

В некоторых случаях в форме отсутствует поле, в другом поле есть, но с пустым значением. Хотелось бы эти случаи как-то различать с минимальным количеством костылей.

linuxnewb
() автор топика
Ответ на: комментарий от anonymous

Спасибо, добрый анон! К сожалению, отсутствие в массиве эквивалентно пустому значению f2, а именно это различие и надо выявить.

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

Я похапе не знаю, но в нормальных языках и фреймворках есть возможность проверить наличие поля в форме. К примеру в django, которая по порогу вхождения не ушла далеко от пых-пыха, есть такая вещь как request.POST.has_key('key')

gnunixon ★★★
()
Ответ на: комментарий от anonymous

упс. совсем позабыл ваш похэпэ

$f2 = array_key_exists('f2', $_REQUEST) ? $_REQUEST['f2'] : null;
anonymous
()
Ответ на: комментарий от linuxnewb

Потому что в учебнике так написано?

А у синего цвета самая короткая длина волны потому что небо голубое?

Мне кажется что в логике что-то не так, точно нельзя пересмотреть? Можно решить накостыляв скрытое поле значение которого яваскрипт менять будет наверное. Может даже можно value самого чекбокса менять.

Kalashnikov ★★★
()
Ответ на: комментарий от gnunixon

1. Пустой чекбокс _не_передается_, никакая джанга не покажет то, чего нет.

2. Что конкретно ты предлагаешь?

linuxnewb
() автор топика
Ответ на: комментарий от gnunixon

Да глупость, неотмеченный чекбокс в принципе не отправится, сервер и язык скрипта вообще ни при чём.

Kalashnikov ★★★
()
Ответ на: комментарий от Kalashnikov

Мне кажется что в логике что-то не так, точно нельзя пересмотреть?

Можно и придется. Но я уже «зациклился», нужен свежий взгляд.

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

1. Угу, ради этого и нужна проверка наличия поля - чтобы исключение не выскочило

2. Тебе-ж анонимус вроде уже предложил аналог того самого has_key для php. Ты его даже благодарил.

Но на самом деле если что-то получается слишком сложным, значит ты что-то делаешь не так. Лучше продумать логику еще лишних полчаса, зато потом проблем меньше будет.

gnunixon ★★★
()
Ответ на: комментарий от Kalashnikov

Лично я считаю такое поведение в приципе неправильным, и никакой стандарт не сделает его менее ущербным.

linuxnewb
() автор топика
Ответ на: комментарий от gnunixon

Да не будет ключа в массиве как в случае не отмеченного чекбокса, так и в случае его отсутствия в форме вообще, запрос cgi скрипту придёт абсолютно одинаковый, никакой has_key не поможет.

Kalashnikov ★★★
()
Ответ на: комментарий от gnunixon

1. Решение воображаемых проблем ненужно.

2. Прочитай мой ответ до конца.

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

Лучше продумать логику еще

Согласен, но у меня больше нет идей. Может, у тебя что-нибудь есть?

linuxnewb
() автор топика
Ответ на: комментарий от exception13

just use hidden fields

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

linuxnewb
() автор топика

Я вижу еще два варианта:

1) использовать радио вместо чекбокса:

<input type="radio" name="f2" id="f2-yes" value="1" /><label for="f2-yes">Yes</label>
<input type="radio" name="f2" id="f2-no" value="0" /><label for="f2-no">No</label>

2) скрытый инпут:

<input type="hidden" name="f2" value="0" />
<input type="chechbox" id="for-f2" />
<script type="text/javascript">
$(function(){
  $('#for-f2').change(function(){
    $('[name=f2]').val( $(this).is(':checked') ? 1 : 0 );
  });
});
</script>

anonymous
()
Ответ на: комментарий от linuxnewb

type=«hidden» как уже говорили
Других вариантов не вижу

Wolfram
()
Ответ на: комментарий от linuxnewb

В контексте моей задачи существует разница между отсутствием отметки в чекбоксе и отсутствием значения.

Т.е. у тебя 3 состояния: чекбокс отмечен, чекбокс не отмечен и еще какое-то мистическое? Может задачу опишешь?

power
()
Ответ на: комментарий от anonymous

Еще селект.

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

linuxnewb
() автор топика
Ответ на: комментарий от power

чекбокс отмечен, чекбокс не отмечен и еще какое-то мистическое?

Почему же мистическое? Вполне реальное: «нет поля чекбокс».

Задача простая: если чекбокс не отмечен или не отмечен, то соответственно изменить данные в БД; если поля нет, то БД не трогать.

linuxnewb
() автор топика

Еще один вариант костыля: проверять наличие поля не во входных данных, а в схеме данных, соответствующей этой форме.

PS: это жесть какая-то, баллмер меня дернул связаться с вебдевом.

linuxnewb
() автор топика

Всё нормально. Если вам нужно контролировать отсутсвие отметки в чекбоксе, вам нужно использовать javascript с триггером, переключающимся при изменении состояния чекбокса, и хранящем состояние чекбоксов. Если слабо знаете js, самым простым выходом будет реализация скрипта на jQuery. С данной либой очень просто создать тригер и навесить переключение его состояний на события. А хранить состояния можно в jQuery Session, это кроссбраузерное решение.

lucentcode ★★★★★
()
Ответ на: комментарий от Slavaz

Красивое решение. Его красота в простоте реализации. Альтернативой которой может быть только скрипт, что не всегда хорошо. Сам про hidden как-то не подумал.

lucentcode ★★★★★
()

В данном случае, с единичным чекбоксом, проблемы вообще нет. Проверяем if(empty($_POST['key'])) и всё прекрасно.

Проблема может быть только при полностью автоматизированной обработке форм во фреймворках. Фреймворк должен знать, нужно ему что-то делать с полем или нет в общем случае, не зная заранее, с какой он формой работает. Но тут, как раз, тоже всё просто — форму генерирует тоже фреймворк и никто не запрещает ему передать имя чекбокса в скрытом списке чекбоксов формы. И дальше — как в начале постинга.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

автоматизированной обработке форм во фреймворках

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

Но тут, как раз, тоже всё просто — форму генерирует тоже фреймворк и никто не запрещает ему передать имя чекбокса в скрытом списке чекбоксов формы

передать имя чекбокса в скрытом списке

Ну, Крон, от кого-кого, а от тебя такого ахтунг-костылинга не ожидал!

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

Ну, Крон, от кого-кого, а от тебя такого ахтунг-костылинга не ожидал!

И как иначе отличить, передавалось пустое значение поля или поля не было совсем? :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

И как иначе отличить, передавалось пустое значение поля или поля не было совсем? :)

Странный checkbox (комментарий)

Согласись, переопределение значения для поля с таким же именем и «передать список имен чекбоксов формы» — вещи немного разные. Или я тебя совсем не понял.

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

Странный checkbox (комментарий)

А, он у меня в игноре.

Решение невалидное. Такое поведение в стандарте не оговорено. Имя элемента формы должно быть уникальным. Так что надёжнее (и ничем не сложнее) передать список чекбоксов.

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Решение невалидное. Такое поведение в стандарте не оговорено. Имя элемента формы должно быть уникальным.

Ну должно и должно. Имхо, такая невалидность гораздо меньшее зло, чем валидное, но кривое поведение чекбокса, чтоб его...

Так что надёжнее

Спорно. Сейчас оно работает, везде, и поломка не предвидется. Когда сломается, тогда и будем проблему решать.

>(и ничем не сложнее) С этим не согласен. Категорически. Костыли — зло.

Но, если в первом случае просто добавляется к строке некая константа, то тут надо целый огород городить: список сформировать, список получить (так, чтоб не пересекался с основными данными), отдельно проверить его и потом уже обработать. Получается целая подсистема, довольно громоздкая, которую — не забывай — еще поддерживать придется.

Проще уж скриптов понапихать. Или имена чекбоксу и хиддену задать как массив. Или на сервере со схемой данных свериться. Конечно, это тоже костыли, но несравнимо менее развесистые. И даже такая скромная цена слишком высока за решение отсутствующей проблемы, я считаю.

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

Сейчас оно работает, везде, и поломка не предвидется. Когда сломается, тогда и будем проблему решать.

Зачем извращаться полагаясь на «авось», когда можно сделать точно также, но в работающем варианте? Собственно, если таких полей больше одного, вариант с hidden-списком чекбоксов даже компактнее будет — один лишний hidden вместо N :)

то тут надо целый огород городить: список сформировать, список получить

По одной-две строчки. И один раз за жизнь фреймворка :)

которую — не забывай — еще поддерживать придется.

Что там поддерживать? Я написал соответствубщий блок кода года четыре уже тому назад и к нему больше к нему не возвращался :)

Или имена чекбоксу и хиддену задать как массив

Один фиг, придётся особый парсинг делать. Получится ничем не лучше моего варианта.

KRoN73 ★★★★★
()
Ответ на: комментарий от Slavaz

А, нет, пардон, это anonymous в игноре. И ЛОР-овская дебильность с игнором всей цепочки :)

KRoN73 ★★★★★
()
Ответ на: комментарий от KRoN73

Что там поддерживать? Я написал соответствубщий блок кода года четыре уже тому назад и к нему больше к нему не возвращался :)

У меня это процесс. Некая методика обрастает кодом постепенно, по мере необходимости добавляются определенные «фишки», устраняются баги, костыли и т.п. Тупо не хватает времени сделать сразу все как надо. К тому же, не всегда наперед известно, какие решения окажутся действительно полезны, или какой креатиффчег стукнет в голову очередному заказчику. Да, получается некоторое количество лишней работы, но это приемлемо. Так набыдлокодился очередной фреймворк.

Один фиг, придётся особый парсинг делать.

Неа. Например, описывается схема, по которой форма и строится, и обрабатывается. При этом проблемы, как в топике, не возникает, т.к. известно, дожен быть там чекбокс или нет. Ну а проблема возникла от необходимости прикрутить более-менее сносный костыль к готовой системе, из-за того, что нелзя использовать этот самый готовый фреймворк.

Конечно, массив костыльнее, и со скриптами тоже не все просто. Но гонять туда-сюда список?

Зачем извращаться полагаясь на «авось»

Я понимаю, что такое UB и принимаю риски с ним связанные, если их перевешивает выгода. Как в данном случае. К тому же, вряд ли этот костыль проживет больше года.

linuxnewb
() автор топика
Ответ на: Это оно от linuxnewb

Тебе уже выше посоветовали использовать hidden fields, на что ты ответил, что это «мегакостыль»

Вообще, спасибо тебе за то, что ты есть :) Благодаря этому у меня всегда будет работа и хорошая ЗП

boombick ★★★★★
()
Ответ на: комментарий от boombick

И тебе спасибо. Всегда забавно наблюдать твою реакцию на новичков.

linuxnewb
() автор топика
Ответ на: комментарий от linuxnewb

Дык это ж легко Потому что чекбокс без значения передаёт «on», если отмечен. Если со значением, то передаёт своё значение А если не отмечен, то вообще не передаёт ничего

Photon79
()
Ответ на: комментарий от linuxnewb

Ну ты-то можешь считать всё что угодно, а вот W3C так не думает

Photon79
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.