Приоритет порядка обработки формы PHP

#php #forms #field #hidden #checkbox

#php #формы #поле #скрыто #флажок

Вопрос:

Я новичок в мире разработки и только начинаю осваивать PHP. У меня есть базовая форма, которая пытается проверить флажки, выбранные пользователем. Мой код приведен ниже. У меня возникает вопрос, почему, когда у меня есть порядок моей формы следующим образом, форма не передает значение NET, PHP или RUBY, а значения, которые передаются автоматически, равны no.

— Код формы, который не работает —

 <form name="checkboxes" method="post" action="form_sample_checkboxes.php">
        <input type="checkbox" name="ch1" value="net" <?php print $ch1status ?>>.NET
            <input type="hidden" name="ch1" value="no">


        <input type="checkbox" name="ch2" value="php" <?php print $ch2status ?>>PHP
        <input type="hidden" name="ch2" value="no">


        <input type="checkbox" name="ch3" value="ruby" <?php print $ch3status ?>>Ruby on Rails
        <input type="hidden" name="ch3" value="no">

        <input type="submit" name="submit" value="submit">
  

Однако, если мой код выглядит следующим образом;

 <form name="checkboxes" method="post" action="form_sample_checkboxes.php">
        <input type="hidden" name="ch1" value="no">
        <input type="checkbox" name="ch1" value="net" <?php print $ch1status ?>>.NET

        <input type="hidden" name="ch2" value="no">
        <input type="checkbox" name="ch2" value="php" <?php print $ch2status ?>>PHP

        <input type="hidden" name="ch3" value="no">
        <input type="checkbox" name="ch3" value="ruby" <?php print $ch3status ?>>Ruby on Rails

        <input type="submit" name="submit" value="submit">
    </form>
  

Флажки отображаются отмеченными. Весь приведенный ниже код.

 <?php

$ch1status = "unchecked";
$ch2status = "unchecked";
$ch3status = "unchecked";

if(isset($_POST["submit"])) {

        if(isset($_POST["ch1"])) {
            if($_POST["ch1"] == "net") {
                $ch1status = "checked";
            }
        }

        if(isset($_POST["ch2"])) {
            if($_POST["ch2"] == "php") {
                $ch2status = "checked";
            }
        }

        if(isset($_POST["ch3"])) {
            if($_POST["ch3"] == "ruby") {
                $ch3status = "checked";
            }
        }

        if ($_POST["ch1"] == "no" amp;amp; $_POST["ch2"] == "no" amp;amp; $_POST["ch3"] == "no") {
            print "There is no such choice";
        }

}

?>
<html>
<head>
    <title>Sample form checkbxoes</title>
</head>
<body>
    <form name="checkboxes" method="post" action="form_sample_checkboxes.php">
        <input type="hidden" name="ch1" value="no">
        <input type="checkbox" name="ch1" value="net" <?php print $ch1status ?>>.NET

        <input type="hidden" name="ch2" value="no">
        <input type="checkbox" name="ch2" value="php" <?php print $ch2status ?>>PHP

        <input type="hidden" name="ch3" value="no">
        <input type="checkbox" name="ch3" value="ruby" <?php print $ch3status ?>>Ruby on Rails

        <input type="submit" name="submit" value="submit">
    </form>

<?php

if(isset($_POST["submit"])) {
    if(isset($_POST["ch1"])) {
        print $_POST["ch1"];
        print $ch1status;
    }

    if(isset($_POST["ch2"])) {
        print $_POST["ch2"];
        print $ch2status;
    }

    if(isset($_POST["ch3"])) {
        print $_POST["ch3"];
        print $ch3status;
    }

}

echo "<pre>";
print_r($_POST);
echo "</pre>";

?>

</body>
</html>
        </form>
  

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

Ответ №1:

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

Другой способ проверки, если флажок не установлен, — это проверить, установлен ли он в $POST -массиве. Если он отсутствует, он обрабатывается как «не проверено».

Ответ №2:

НЕОПРЕДЕЛЕННЫЕ ИНДЕКСЫ:

Это связано с тем, что флажки отправляются только в том случае, если они установлены. Одна вещь, которую вы можете сделать, это всегда проверять переменную с помощью isset (например, isset($_POST['ch1']) ) перед их использованием; другая — присвоить вашим флажкам одинаковые имена с [] после имени (например, name="languages[]" ), а затем сделать что-то вроде этого:

 // Create a list of languages that are OK (remember, some users are malicious)
$languages = array('net','php','ruby');
// Compile a list of the answers the user picked; force it to be an 
// array by either explicitly casting to an array, or using an empty array
//  if none chosen
$picked = isset($_POST['languages']) ? (array)$_POST['languages'] : array();

// first, use array_intersect to remove entries present in one and not the other
// i.e. invalid entries from the client or entries not picked from the whole list
// then, "flip" the array so that the values become keys, 
// because isset is faster than in_array
$valid_langs = array_flip(array_intersect($languages, $picked));

// check on languages
if (isset($valid_langs['php'])) { /* PHP picked */ }
if (isset($valid_langs['net'])) { /* NET picked */ }
if (isset($valid_langs['ruby'])) { /* Ruby picked */ }
  

Более простое решение:

 <form>
    <input type="checkbox" name="php" value="yes" />
    <input type="checkbox" name="net" value="yes" />
    <input type="checkbox" name="ruby" value="yes" />
</form>
  

 <?php
$php = $net = $ruby = 'unchecked';
if (!isset($_POST['php'],$_POST['net'],$_POST['ruby'])) {
    echo 'There is no such choice';
}
else {
    if (isset($_POST['php']) amp;amp; $_POST['php'] == 'yes') {
        $php = 'checked';
    }
    if (isset($_POST['net']) amp;amp; $_POST['new'] == 'yes') {
        $net = 'checked';
    }
    if (isset($_POST['ruby']) amp;amp; $_POST['ruby'] == 'yes') {
        $ruby = 'checked';
    }
}
// ... snip ...
  

Существует великое множество способов сделать это. Надеюсь, вам будет интересно изучить многие из них.

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

1. Ого. Это просто пролетело мимо моей головы. Понятия не имеете, как работают массивы или такие операторы, как $picked = isset($_POST[‘languages’])? (массив)$_POST[‘languages’] : array();. Есть ли что-нибудь попроще для новичка, пока я разбираюсь, что такое массивы, как они работают и т.д.?

2. Я добавил более простое решение, хотя стоит упомянуть, что $_POST это массив, так что вы не совсем незнакомы с ними =)

3. Вау, кажется намного чище, чем мой код. Вопрос. 1. Почему объявление $ php = $net = $ruby = ‘непроверено’; я понятия не имел, что вы можете написать isset($_POST[‘php’],$_POST[‘net’], $_POST[‘ruby’]. Я знаю, что $_POST — это массив, однако я не знаю, что делает массив, когда вы его используете и т.д.

4. Это делается для их предварительной инициализации, что на самом деле не обязательно в PHP, если, конечно, позже не возникнет логическая ошибка, если они не будут установлены, например, если они установлены только в условии if, которое не срабатывает, и используются в условии if позже.

5. Извините, Феникс. Я не совсем понял, что вы имели в виду. Не могли бы вы, пожалуйста, пояснить? Извините, я новичок.

Ответ №3:

Весь Php работает на стороне сервера, поэтому для предотвращения их отправки вам потребуется проверка на стороне клиента. Самая простая проверка на стороне клиента — с помощью javascript или плагина проверки в jQuery, если вы уже используете jQuery (что и должно быть, если вы планируете использовать AJAX в любой момент).

И да, вы можете избавиться от этих скрытых входных данных.

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

1. Спасибо, Брайан. Да, я знаю, что все это на стороне сервера, и я могу использовать проверку на стороне клиента, однако хотел бы узнать, как проверять данные на стороне сервера.

2. Также, если я удаляю скрытые поля формы, я получаю ошибки неопределенного индекса.

3. Никогда не доверяете клиенту? Действительно? Я обнаружил, что проверка на стороне клиента является необходимостью. В идеале, конечно, вы используете оба варианта, но полностью отказываться от них довольно глупо, особенно когда имеешь дело с отправкой формы. Заблокируйте отправку на уровне клиента, и вы сэкономите нагрузку на сервер. Или вы из тех парней, которые работают без КАПЧИ?

Ответ №4:

Вам не нужны эти скрытые поля. Удалите их, и это должно сработать.

РЕДАКТИРОВАТЬ: Ознакомьтесь с этой модификацией

     $ch1status = "unchecked";
    $ch2status = "unchecked";
    $ch3status = "unchecked";

    if(isset($_POST["submit"])) {

        if(@$_POST["ch1"] != "") {
            $ch1status = "checked";
        }

        if(@$_POST["ch2"] != "") {
            $ch2status = "checked";
        }

        if(@$_POST["ch3"] != "") {
            $ch3status = "checked";
        }

        if (@$_POST["ch1"] . @$_POST["ch2"] . @$_POST["ch3"] == "") {
            print "There is no such choice";
        }

    }

?>
<html>
    <head>
        <title>Sample form checkbxoes</title>
    </head>
    <body>
        <form name="checkboxes" method="post" action="form_sample_checkboxes.php">
            <input type="checkbox" name="ch1" value="net" <?php echo $ch1status; ?>>.NET

            <input type="checkbox" name="ch2" value="php" <?php echo $ch2status; ?>>PHP

            <input type="checkbox" name="ch3" value="ruby" <?php echo $ch3status; ?>>Ruby on Rails

            <input type="submit" name="submit" value="submit">
        </form>

        <?php

            if(isset($_POST["submit"])) {
                if(isset($_POST["ch1"])) {
                    print $_POST["ch1"];
                    print $ch1status;
                }

                if(isset($_POST["ch2"])) {
                    print $_POST["ch2"];
                    print $ch2status;
                }

                if(isset($_POST["ch3"])) {
                    print $_POST["ch3"];
                    print $ch3status;
                }

            }

            echo "<pre>";
            print_r($_POST);
            echo "</pre>";

        ?>

    </body>
</html>
  

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

1. Они этого не делают. Если у меня нет скрытых полей формы, все мои отображаемые ошибки неопределенного индекса.

2. используйте isset($_POST['php']) и т.д., чтобы проверить наличие полей, прежде чем пытаться с ними работать. Флажки создают переменные POST только в том случае, если они установлены.

3. Спасибо удалено, однако, как мне использовать isset($_POST[]) с инструкцией «($_POST[«ch1»] == «нет» amp;amp; $_POST[«ch2»] == «нет» amp;amp; $ _POST[«ch3»] == «нет»)», т. е. как мне проверить несколько полей формы одновременно?

4. Вы должны выполнять каждую из них по отдельности. например. if(isset($_POST[‘ch2’])) //do stuff

5. на самом деле, isset() и unset() оба будут принимать несколько аргументов, например isset($_POST['ch1'],$_POST['ch2'],$_POST['ch3']) — note, это pass / fail ; если хотя бы один из них не задан, он возвращает false; это также зависит от логики короткого замыкания.