PHP 4 на практике

       

Вводные примеры


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

Пример 1: передача данных формы из одного сценария в другой

В первом примере представлена характерная ситуация — когда пользовательские данные вводятся на одной странице и отображаются на другой. В листинге 10.2 приведен код формы для ввода имени пользователя и адреса электронной почты. Когда пользователь щелкает на кнопке отправки данных (кнопка Go!), форма обращается к странице, приведенной в листинге 10.3. В свою очередь, листинг 10.3 выводит переменные $name и $mail, переданные с запросом.

Листинг 10.2.

Простая форма

<html>

<head>

<title>Listing 10-2</title>

</head>

<body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="#808040">

<form action="listingl0-3.php" method="post">

<b>Give us some information!</b><br>

Your Name:<br>

<input type="text" name="name" size="20" maxlength="20" value=""><br>

Your Email:<br>

<input type="text" name="email" size="20" maxlength="40" value=""><br>

<input type="submit" value="go!">

</form>

</body> </html>

Листинг 10.3.

Отображение данных, введенных в листинге 10.1

<html> <head>

<title>Listing 10-3</title>

</head>

<body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="#808040">

<?

// Вывести имя и адрес электронной почты.

print "Hi. $name!. Your email address is $email";

?>

</body> </html>

В общих чертах происходит следующее: пользователь заполняет поля формы и нажимает кнопку отправки данных. Управление передается странице, приведенной в листинге 10.3, где происходит форматирование и последующее отображение данных. Как видите, все просто.


Существует и другой способ обработки данных форм, при котором используется всего один сценарий. К недостаткам этого способа относятся увеличение сценария и как следствие — затруднения с редактированием и сопровождением. Впрочем, есть и достоинства — уменьшение количества файлов, с которыми вам приходится работать. Более того, в этом варианте сокращается избыточный код при проверке ошибок (эта тема рассматривается ниже в данной главе). Конечно, в некоторых ситуациях работать с одним сценарием неудобно, но, по крайней мере, вы должны знать об этой возможности. В примере 2 воспроизводится пример 1, но с использованием лишь одного сценария.

Пример 2: альтернативная обработка формы (с одним сценарием)

Обработка данных формы в одном сценарии реализуется относительно просто. Вы проверяете, были ли присвоены значения переменным формы. Если значения присвоены, сценарий обрабатывает их (в нашем примере — просто выводит), а если нет — отображает форму. Решение о том, было ли задано значение переменной или нет, принимается при помощи функции strcmp( ), описанной в главе 8. Пример реализации формы с одним сценарием приведен в листинге 10.4. Обратите внимание: атрибут action формы ссылается на ту же страницу, в которой определяется сама форма. Условная команда i f проверяет состояние переменной скрытого поля с именем $seenform. Если значение $seenform не задано, форма отображается в браузере, а если задано — значит, форма была заполнена пользователем и введенные данные обрабатываются сценарием (в данном примере — просто выводятся в браузере).

Листинг 10.4.

Ввод данных на форме в одном сценарии

<html>

<head>

<title>Listing 10-4</title>

</head>

<body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="f808040">

<?

// Все кавычки внутри $form должны экранироваться,

// в противном случае произойдет ошибка.

$form = "

<form action=\"listing10-4.php\" method=\"post\">



<input type=\"hidden\" name=\"seenform\" value=\"y\">

<b>Give us some information!</b><br>

Your Name:<br>

<input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" value=\"\"><br>

Your Email:<br>

<input type=\"text\" name=\"email\" size=\"20\" maxlength=\"40\" value=\"\"><br>

<input type=\"submit\" value=\"subscribe!\">

</form>";

// Если форма ранее не отображалась, отобразить ее.

// Для проверки используется значение скрытой переменной $seenform.

if ($seenform != "у"):

print "$form";

else :

print "Hi. $name!. Your email address is $email";

endif;

?>

</body>

</html>

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

Теперь, когда вы представляете, как просто выполняются операции с формами, мы переходим к интересному примеру — автоматической отправке данных пользователя по заданному адресу электронной почты. Эта возможность реализована в примере 3.

Пример 3: автоматическая отправка данных по электронной почте

Вывести пользовательские данные в браузере несложно, но вряд ли это можно назвать содержательной обработкой пользовательского ввода. Один из способов обработки информации заключается в ее отправке по электронной почте — например, администратору сайта. Хотя при помощи гиперссылки mailto: можно отправить сообщение прямо из браузера, следует учитывать, что внешние приложения электронной почты настроены не на каждом компьютере. Следовательно, отправка сообщений с web-формы более надежно гарантирует, что сообщение будет доставлено адресату.



В следующем разделе, mail( ), создается небольшая форма, в которой пользователь вводит информацию и комментарии по поводу сайта. Затем данные форматируются соответствующим образом и передаются стандартной функции РНР mail( ). Но прежде чем переходить к построению формы, необходимо предварительно рассмотреть синтаксис функции mail( ).

mail ( )

Функция mail( ) отправляет сообщение заданному адресату по электронной почте. Синтаксис функции mail( ):

boolean mail (string получатель, string тема, string сообщение [, string доп_заголовки])

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

В системе UNIX функция mail( ) использует утилиту sendmail. В Windows эта функция работает лишь при наличии установленного почтового сервера или если функция mail( ) связана с работающим сервером SMTP. Эта задача решается модификацией переменной SMTP в файле php.ini.

Если вы сделали все необходимое и функция mail( ) работает в вашей системе, попробуйте выполнить следующий фрагмент (конечно, адрес youraddress@yourserver.com заменяется вашим настоящим адресом электронной почты):

$email = "youraddress@yourserver.com";

$subject = "This is the subject";

$message = "This is the message";

$headers = "From: somebody@somesite.com";

mail ($email, $subject, $message, $headers);

Хотя при обширной переписке, конечно, следует использовать специализированные почтовые программы вроде majordomo (http://www.greatcircle.com/majordomo), в простых случаях функции РНР mail( ) оказывается вполне достаточно.

Итак, после знакомства с функцией mail( ) можно применить ее на практике. В листинге 10.5 показано, как получить информацию от пользователя и отправить ее по адресу, заданному администратором сценария.

Листинг 10.5.

Пересылка пользовательских данных функцией mail( )



<html>

<head>

<title>Listing 10-5</title>

</head>

<body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="#808040">

// Все кавычки внутри $form должны экранироваться.

// в противном случае произойдет ошибка.

$form = "

<form action=\"listing10-5.php\" method=\"post\">

<input type=\"hidden\" name=\"seenform\" value=\"y\">

<b>Send us your comments!</b><br>

Your Name:<br>

<input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" value=\"\"><br>

Your Email:<br>

<input type=\"text\" name-\"email\" size=\"20\" maxlength=\"40\" value=\"\"><br>

Your Comments:<br>

<textarea name=\"comments\" rows=\"3\" cols=\"30\"></textarea><br>

<input type=\"submit\" value=\"submit!\">

</form>

// Если форма ранее не отображалась, отобразить ее.

//

Для проверки используется значение скрытой переменной $seenform.

if ($seenform != "у") :

print "$form"; else :

// Переменная $recipient определяет получателя данных формы

$recipient = "yourname@youremail.com";

// Тема сообщения

$subject = "User Comments ($name)";

// Дополнительные заголовки $headers = "From: $email";

// Отправить сообщение или выдать сообщение об ошибке

mail($recipient, $subject, $comments, $headers) or die("Could not send email!");

// Вывести сообщение для пользователя

print "Thank you $name for taking a moment to send us your comments!";

endif;

?>

</body>

</html>

Неплохо, правда? Листинг 10.5 работает так же, как листинг 10.4; сначала мы проверяем, отображалась ли форма ранее. Если это происходило, программа вызывает функцию mail( ) и пользовательские данные отправляются по адресу, определяемому переменной $recipient. Затем в браузере выводится благодарственное сообщение для пользователя.



Простейшим расширением этого примера будет отправка благодарственного сообщения по электронной почте (вторым вызовом mail( )). Следующий пример развивает эту идею — пользователю предлагается на выбор несколько бюллетеней. Выбранные бюллетени отправляются по электронной почте.

Пример 4: отправка запрашиваемой информации по электронной почте

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

Информационные сообщения хранятся в отдельных файлах. В нашем примере используются три текстовых файла:



  • site.txt — информация о сайте;


  • team.txt — информация о талантливых разработчиках сайта;


  • events.txt — приглашение на очередное мероприятие.


  • Исходный текст примера приведен в листинге 10.6.

    Листинг 10.6.

    Отправка информации, запрашиваемой пользователем

    <html>

    <head>

    <title>Listing10-5</title>

    </head>

    <body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="#808040">

    <?

    $form = "

    <form action=\"Listing10-6.php\" method=\"post\">

    <input type=\"hidden\" name=\"seenform\" value=\"y\">

    <b>Receive information about our site!</b><br>

    Your Email:<br>

    <input type=\"text\" name=\"email\" size=\"20\" maxlength=\"40\" value=\"\"><br>

    <input type=\"checkbox\" name=\"information[site]\" value=\"y\">Site Architecture<br>

    <input type=\"checkbox\" name=\"information[team]\" value=\"y\">Development Team<br>



    <input type=\"checkbox\" name=\"information[events]\" value=\"y\">Upcoming Events<br>

    <input type=\"submit\" value=\"send it to me!\">

    </form>":

    if ($seenform != "y") :

    print "$form"; else :

    $headers = "From: devteam@yoursite.com";

    // Перебрать все пары "ключ/значение"

    while ( list($key, Sval) = each ($information) ) :

    // Сравнить текущее значение с "у" if ($val == "у") :

    // Построить имя файла, соответствующее текущему ключу

    $filename = "$key.txt":

    $subject = "Requested $key information";

    // Открыть файл

    $fd = fopen ($filename, "r");

    // Прочитать содержимое всего файла в переменную $contents = fread ($fd. filesize ($filename));

    // Отправить сообщение

    mail($email, $subject, $contents, $headers) or die("Can't send email!");; fclose($fd);

    endif;

    endwhile;

    // Известить пользователя об успешной отправке

    print sizeof($information)." informational newsletters

    have been sent to $email!";

    endif;

    ?>

    </body>

    </html>

    В листинге 10.6 мы перебираем пары «ключ/значение» в цикле while и отправляем только те бюллетени, у которых значение равно у. Следует помнить, что имена текстовых файлов должны соответствовать ключам массива

    (site.txt, team.txt и events.txt). Имя файла строится динамически по ключу, после чего файл открывается по имени и его содержимое загружается в переменную ($contents). Затем переменная $contents передается функции mail( ) в качестве параметра.

    В следующем примере пользовательские данные сохраняются в текстовом файле.

    Пример 5: сохранение пользовательских данных в текстовом файле

    Пользовательские данные сохраняются в текстовом файле для последующего статистического анализа, поиска и т. д. — короче, любой обработки по вашему усмотрению. В листинге 10.7, как и в предыдущих примерах, данные формы обрабатываются в одном сценарии. Пользователю предлагается ввести четыре объекта данных: имя, адрес электронной почты, язык и профессию. Введенная информация сохраняется в текстовом файле user_information.txt. Элементы данных разделяются символами «вертикальная черта» (|).



    Листинг 10.7.

    Сохранение пользовательской информации в текстовом файле

    <html>

    <head>

    <titlexisting 10-7</title>

    </head>

    <body bgcolor="#ffffff" text="#000000" link="#cbda74" vlink="#808040" alink="#808040">

    <?

    // Создать форму

    $form = "

    <form action=\"Listing10-7.php\" method=\"post\">

    <input type=\"hidden\" name=\"seenform\" value=\"y\">

    <b>Give us your personal info!</fb><br>

    Your Name:<br>

    <input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" value=\"\"><br>

    Your Email:<br>

    <input type=\"text\" name"=\"email\" size=\"20\" maxlength=\"20\" value=\"\"><br>

    Your Preferred Language:<br>

    <select name=\"language\">

    <option value=\"\">Choose a language:

    <option value=\"English\">English

    <option value=\"Spanish\">Spanish

    <option value=\"Italian\">Italian

    <option value=\"French\">French

    <option value=\"Japanese\">Japanese

    <option value=\"newyork\">NewYork-ese

    </select><br>

    Your Occupation:'"ibr>

    <select name=\"job\">

    <option value=\"\">What do you do?:

    <option value=\"student\">Student

    <option value=\ "programmed ">Programmer

    <option value=\"manager\">Project Manager

    <option value=\"slacker\">Slacker

    <option value=\"chef\">Gourmet Chef

    </select><br>

    <input type=\"submit\" value=\"submit!\">

    </form>";

    // Заполнялась ли форма ранее? if ($seenform != "у") :

    print "$form"; else :

    $fd = fopen("useMnformation.txt", "a");



    // Убедиться, что во введенных данных не встречается

    // вертикальная черта.

    $name = str_replace("|", "", $name);

    $email = str_replace("|", "", $email);

    // Построить строку с пользовательскими данными

    $user_row = $name." ".$email."|".$language." ".$job."\n";

    fwrite($fd, $user_row) or die("Could not write to file!");

    fclose($fd);

    print "Thank you for taking a moment to fill out our brief questionnaire!":

    endif;

    ?>

    </body>

    </html>

    Обратите внимание на фрагмент, в котором мы проверяем, что пользователь не включил в имя или адрес электронной почты символы «вертикальная черта» (|). Функция str_replace( ) удаляет эти символы, заменяя их пустой строкой. Если бы это не было сделано, пользовательские символы | нарушили бы структуру файла данных и существенно затруднили (а то и сделали невозможным) его правильную обработку.

    При работе с относительно малыми объемами информации вполне можно обойтись текстовыми файлами. Однако при большом количестве пользователей или объеме сохраняемой информации для хранения и обработки данных, введенных в форме, лучше воспользоваться базой данных. Эта тема подробно рассматривается в главе 11.

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


    Содержание раздела