Формы и PHP
Создание и использование форм в PHP
Язык PHP изначально разрабатывался как язык для Web-программирования. Конечно, вы можете запустить PHP из командной строки, но фактически случаи использования PHP вне Web-приложений очень редки. Как правило PHP используется вместе с HTML-формами.
Вы создаете форму с использованием HTML, затем пользователь вводит данные в эту форму и инициирует ее передачу, браузер пересылает данные серверу в форме массива.
В этом разделе мы определим, что такое массив данных, рассмотрим способы работы с данными в формах. Вы также познакомитесь с конструкциями, управляющими ходом выполнения PHP-скрипта, такими как циклы и условные операторы if-then.
Создание форм в HTML
Начнем с создания страницы регистрации для вашего приложения. На этой странице пользователи будут вводить свои данные, а вы будете утверждать их, то есть выполнять некоторые проверки, прежде чем переслать данные в базу. Для начала просто создадим форму для ввода. Создадим новый файл
registration.php и поместим в него следующий текст:
<html>
<head><title>Workflow System</title></head>
<body>
<h1>Register for an Account:</h1>
<form action="registration_action.php" method="GET">
Username: <input type="text" name="name" /><br />
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="pword" /><br />
<input type="submit" value="GO" />
</form>
</body>
</html>
|
Таким образом, мы имеем простую форму, которая содержится внутри HTML-тега form, в ней есть текстовое поле для ввода пароля и клавиша для отсылки данных. Сохраните этот текст в файл с именем registration.php и поместите файл в корневую папку с документами для вашего сервера, затем откройте браузер с адресом http://localhost/registration.php. Результат работы вашего браузера будет похож на то, что можно видеть ниже, на Рисунке 3.
Рисунок 3. Форма для регистрации
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Обратите внимание на то, что в поле для ввода пароля не отображаются символы, которые вы набираете, вместо этого появляются звездочки. Что же происходит, когда пользователь нажимает клавишу
GO?
Передача данных из формы
Рассмотрим подробнее формат элемента form нашей формы.
<form action="registration_action.php" method="GET">
|
В этом элементе определено два параметра. Первый, action, сообщает браузеру куда посылать информацию. В нашем случае ссылка ведет к тому файлу, который мы создали ранее, registration_action.php. Второй параметр,
method, сообщает браузеру как передавать данные.
Посмотрим, как это работает. Введите какие-либо данные и нажмите кнопку GO. Вы увидите нечто похожее на
Рисунок 4.
Рисунок 4. Вывод данных, введенных в форму
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
В том случае, если вы не ввели данные, но нажали кнопку, форма будет работать также, поскольку у нас пока еще не налажен прием введенных данных. Обратите внимание на URL, который появился в поле адреса браузера.
http://localhost/registration_action.php?name=roadnick&email=
ibmquestions%40nicholaschase.com&pword=supersecretpassword
|
Заметьте, что каждому элементу формы в URL соответствует пара имя-значение и эти пары разделены амперсандами.
Такой вид URL обусловлен тем, что мы использовали в качестве метода передачи GET. Далее мы рассмотрим использование метода POST, но прежде научимся принимать данные из формы в
PHP-страницу.
Прием данных из формы
Рассмотрим, каким образом данные, введенные в HTML-форму, можно сделать доступными в принимающей PHP-странице.
Внесите следующие изменения в файл registration_action.php:
...
<body>
<p>You entered:</p>
<?php
$username = $_GET['name'];
$password = $_GET['pword'];
echo "<p>Username = " . $username . "</p>";
echo "<p>Password = " . $password . "</p>";
?>
</body>
</html>
|
Значения переменных будут теперь выбираться по имени из массива $_GET. Чуть ниже мы поговорим о массивах подробнее, а сейчас попробуйте обновить окошко браузера, вы увидите, что введенные нами данные появились на своих местах, как показано на
Рисунке 5.
Рисунок 5. Введенные данные отображаются в браузере
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Вы можете извлечь любую часть переданной информации по имени, но есть и другие возможности работы с массивами.
Массивы
В PHP можно организовывать массивы данных, то есть списки значений, это позволяет легко перемещать одновременно целые группы данных.
Например, создадим массив из трех элементов и передадим его для вывода на страницу:
$formnames = array("name", "email", "pword");
echo "0=".$formnames[0]."<br />";
echo "1=".$formnames[1]."<br />";
echo "2=".$formnames[2]."<br />";
|
Функция array() возвращает переменную, которая является массивом. (О том, что такое функция, мы будем говорить позже, пока же достаточно понимать, что функцию можно вызвать и что она возвращает значение того или иного типа, которое вы приписываете переменной.)
Результат работы этого скрипта будет такой:
0=name<br />
1=email<br />
2=pword<br />
|
Заметьте, что первое значение в массиве имеет индекс, равный 0, но не 1. Заметьте также, что мы выделяем нужное значение, добавив индекс в квадратных скобках к имени массива. Подобным же образом мы получали доступ к значениям переменной формы. Переменная $_GET является именем массива специального типа,
ассоциативного массива, к элементам которого обращаются не по индексам, а по
ключам.
В тот момент, когда вы отсылаете свою форму, вы по существу дела создаете ассоциативный массив:
$_GET = array("name" => "roadnick",
"email" => "ibmquestions@nicholaschase.com",
"pword" => "supersecretpassword");
|
Именно этот факт позволяет вам впоследствии выделить отдельные значения, например, $_GET["name"], имена переменных в этом случае играют роль ключей.
Получение информации о массиве
Ассоциативные массивы крайне полезны при передаче данных между формами, но при их использовании может возникнуть трудность, далеко не всегда известна структура массива.
Такая ситуация может быть, например, если ассоциативный массив был получен в результате выполнения запроса к базе данных.
В PHP есть две функции, которые облегчают использование таких массивов:
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
echo "<p>" . $form_names[0] . " = " . $form_values[0] . "</p>";
echo "<p>" . $form_names[1] . " = " . $form_values[1] . "</p>";
echo "<p>" . $form_names[2] . " = " . $form_values[2] . "</p>";
?>
</body>
</html>
|
Функции array_keys() и array_values() возвращают обыкновенные массивы, к элементам которых можно обращаться при помощи числовых индексов, как показано ниже на
Рисунке 6.
Рисунок 6. Извлечение данных из массива с использованием числовых индексов
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Этот способ работы с массивами также имеет неудобства. Например, вы можете не знать, сколько всего элементов в ассоциированном массиве. В PHP существуют и другие способы обращения с ассоциированными массивами. Следующим шагом мы рассмотрим два таких способа.
Использование цикла for-next
Задача последовательный обработки некоторого числа однотипных значений возникает очень часто. Для ее выполнения применяется такая конструкция как цикл. Вот один из примеров цикла:
for ($i = 0; $i < 10; $i++) {
echo $i . " ";
}
|
Результат его работы будет следующим:
Рассмотрим синтаксис выражения for. Первоначально PHP приписывает значение 0 переменной $i.
Цикл продолжается до тех пор, пока значение переменной $i остается меньше 10, на каждом шаге цикла значение переменной
$i увеличивается на единицу.
Поскольку у нас есть возможность узнать, сколько всего значений содержит массив $_GET, мы легко можем организовать цикл, который отобразит все значения, переданные нам из формы:
<body>
<p>You entered:</p>
<?php
$form_names = array_keys($_GET);
$form_values = array_values($_GET);
for ($i = 0; $i < sizeof($_GET); $i++) {
echo "<p>".$form_names[$i]." = " . $form_values[$i] . "</p>";
}
?>
</body>
</html>
|
Функция sizeof() возвращает число элементов массива, в нашем случае массива $_GET. Вы можете использовать
возвращаемое этой функцией значение в условном операторе, который останавливает выполнение цикла, результат работы цикла показан ниже на Рисунке 7.
Рисунок 7. Использование функции sizeof для остановки цикла
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Для работы с ассоциированным массивом $_GET вы можете использовать и другой тип цикла, цикл с ключевым словом foreach.
Использование цикла foreach
Ассоциированные массивы настолько часто используются в PHP, что для работы с ними была создана специальная конструкция, которая позволяет получать доступ к данным, минуя ключи. Вместо этого вы можете использовать цикл foreach, он позволяет манипулировать с данными массива напрямую. Давайте рассмотрим пример кода:
...
<?php
foreach ($_GET as $value) {
echo "<p>" . $value . "</p>";
}
?>
|
На первом шаге цикла будет извлечено первое значение из массива $_GET, это значение будет приписано переменной $value, затем это значение выводится командой echo. Затем цикл повторяется, переменной $value приписывается второе значение и так далее, цикл работает до тех пор, пока в массиве $_GET еще остаются необработанные элементы. Результат работы этого цикла будет следующим:
<p>roadnick</p>
<p>ibmquestions@nicholaschase.com</p>
<p>supersecretpassword</p>
|
Эта конструкция позволяет извлекать не только значения элементов ассоциированного массива, но и ключи:
...
<?php
foreach ($_GET as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
?<
...
|
Такой вариант кода приведет нас к результату, который мы уже видели выше:
Рисунок 8. Исходный вариант вывода
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Повторяющиеся значения в формах
Иногда возникает ситуация, когда в форме должно быть введено несколько значений для переменной с одним и тем же именем. Примером может служить поле пароля pword. Поскольку пользователи не могут видеть символы пароля, которые они набирают, то вы можете попросить их ввести пароль дважды, для того чтобы убедиться, что они не сделали ошибку при вводе:
...
Username: <input type="text" name="name" /><br />
Email: <input type="text" name="email" /><br />
Password: <input type="password" name="pword[]" /><br />
Password (again): <input type="password" name="pword[]" /><br />
<input type="submit" value="GO" />
...
|
Заметьте, что имя поля pword несколько изменилось. Поскольку это поле должно содержать несколько значений, то оно само стало массивом. Таким образом, массив передаваемых данных для этой формы будет содержать в качестве одного из своих элементов другой массив. Когда вы нажмете кнопку отправки формы, то в поле адреса возникнет следующий URL:
http://localhost/registration_action.php?name=roadnick&email=ibmquestions%40nicholas
chase.com&pword[]=supersecretpassword&pword[]=supersecretpassword
|
При этом в процессе обработки будет создан массив:
$passwords = array("supersecretpassword", "supersecretpassword");
$_POST = array("name"=>"roadnick",
"email"=>"ibmquestions@nicholaschase.com",
"pword"=>$passwords);
|
В этом варианте для просмотра значения пароля вы должны обращаться к соответствующей переменной как к массиву с числовым индексом:
...
foreach ($_GET as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_GET["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
...
|
Если вы отошлете форму (не забудьте обновить страницу), то можете заметить некоторые изменения, как показано ниже на Рисунке 9.
Рисунок 9. Новый вариант вывода
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Обратите внимание, в поле, где раньше отображался пароль, появилось слово Array, элементы самого массива отображены ниже.
Отличия методов
GET и POST
До сих пор для передачи данных из формы мы использовали метод GET, главным неудобством и ограничением этого метода является тот факт, что передаваемые данные помещаются прямо в
адрес URL. В некоторых случаях это вполне допустимо, в других -- нет. Например, вам требуется передать из формы большой блок данных из поля типа textarea, обычно такой тип используется для размещения комментариев. Как правило,
Web-сервер ограничивает число символов, которые можно поместить в URL-адрес, таким образом передать данные посредством метода GET просто невозможно.
Согласно принятым стандартам технологии Web-программирования, метод GET не следует использовать для передачи данных в скрипты, которые могут иметь "побочные эффекты", а фактически любой скрипт, в котором происходит обработка данных, обладает этим свойством. До сих пор мы только отображали введенные данные, обработки не происходило, но если мы хотим добавить запись в базу данных, то это уже обработка, которая может иметь побочный эффект.
Тот факт, что метод GET передает данные в URL-адресе открытым, то есть, доступным для просмотра образом, не только влияет на безопасность системы, но обладает и другими неудобствами. Например, пользователь может сделать закладку на этот адрес, что приведет к тому, что операция будет выполняться много раз; поисковые машины, которые индексируют URL-адреса, могут перехватить данные, направляемые в вашу базу и так далее.
Поэтому в большинстве случаев имеет смысл пользоваться методом POST, который передает данные в теле запроса, а не в заголовке, как метод GET.
Использование метода POST
Внешне использование метода POST мало отличается от использования метода GET. Сначала внесем изменения в файл
registration.php:
...
<h1>Register for an Account:</h1>
<form action="registration_action.php" method="POST">
Username: <input type="text" name="name" /><br />
...
|
При отсылке формы вы увидите, что содержание URL-адреса изменилось:
http://localhost/registration_action.php |
Изменения нужны и в файле registration_action.php, для приема данных вместо массива $_GET будет использоваться массив $_POST:
...
<body>
<p>You entered:</p>
<?php
foreach ($_POST as $key=>$value) {
echo "<p>".$key." = " . $value . "</p>";
}
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
?>
</body>
</html>
|
Дальнейшая работа с массивом $_POST происходит точно так же, как и с массивом $_GET.
Контроль данных: условный оператор if-then
Выше мы попросили пользователя ввести пароль дважды. Теперь посмотрим, как можно проверить, не было ли сделано ошибки при вводе пароля. Для этого используем условный оператор if-then:
...
$passwords = $_POST["pword"];
echo "First password = ".$passwords[0];
echo "<br />";
echo "Second password = ".$passwords[1];
if ($passwords[0] == $passwords[1]) {
echo "<p>Passwords match. Thank you.</p>";
} else {
echo "<p>Passwords don't match. Please try again.</p>";
}
...
|
В заголовке условного оператора в скобках помещено некоторое выражение (в нашем примере это
$passwords[0] == $passwords[1]), которое может быть истинно (TRUE) или ложно (FALSE). Если оно истинно, то PHP выполняет тот оператор, который следует за условным выражением, это может быть блок операторов в фигурных скобках. Если оно ложно, что выполняется блок, следующий за ключевым словом else, а если его нет, то скрипт переходит к выполнению следующего оператора.
Обратите внимание на то, что мы написали $passwords[0] == $passwords[1], а не
$passwords[0] = $passwords[1], то есть использовали двойной знак равенства.
Это не случайно. Простой знак равенства работает как оператор присваивания, то есть, значение $passwords[0] в этом случае просто станет равным
$passwords[1]. Нам же надо совсем не это, мы хотим сравнить значения переменных и поэтому используем оператор сравнения -- двойное равенство.
Ниже, на Рисунке 10, показана страница, которую увидит пользователь в том случае, если он сделал ошибку при вводе пароля.
Рисунок 10. Предупреждение об ошибке при вводе пароля
| XML error: The image is not displayed because the width is greater than the maximum of 500 pixels. Please decrease the image width. |
Для формирования более сложных логических выражений можно применять логические операторы, например, оператор И
(&&) и оператор ИЛИ
(||). Рассмотрим следующее выражение:
if (($today == "Monday") && ($status == "Not a holiday")) {
echo "GO TO WORK!!!";
}
|
Значение логического выражения в скобках будет истина (TRUE) в том случае, если сегодня понедельник (Monday) И этот день не является праздничным.
|