<?include'h.php';?>
<html><head>
		<title>Учебник PHP, Глава 10</title>
		<meta http-equiv="Content-type" content="text/html; charset=Windows-1251">
		</head>
		
      <DIV class=infotxt>
      <LI><A href="#a">Глава 10. Формы</A> 
      <UL>
        <LI><A href="#b">Общие сведения о 
        формах</A> 
        <UL>
          <LI><A href="#c">Элементы форм, 
          ориентированные на ввод с клавиатуры</A> 
          <LI><A href="#d">Элементы форм, 
          ориентированные на ввод с мыши</A> 
          <LI><A href="#e">Все вместе: пример 
          формы</A> </LI></UL>
        <LI><A href="#f">Формы и PHP</A> 
        <UL>
          <LI><A href="#g">Вводные примеры</A> 
          </LI></UL>
        <LI><A href="#h">Проверка ошибок</A> 
        <LI><A href="#i">Динамическое 
        конструирование форм</A> 
        <LI><A href="#j">Проект: гостевая 
        книга</A> 
        <LI><A href="#k">Итоги</A> </LI></UL>
      <UL></UL><A name=a></A>
      <P>&nbsp;</P>
      <P>ГЛАВА 10</P>
      <P>Формы</P>
      <P>Получение и обработка данных, введенных пользователем, стали 
      неотъемлемой частью большинства успешных web-сайтов. Бесспорно, 
      возможности накопления статистики, проведения опросов, хранения 
      персональных настроек и поиска выводят Web на принципиально новый уровень 
      — без них эта среда обладала бы минимальной интерактивностью.</P>
      <P>Ввод информации в основном реализуется с применением форм HTML. 
      Несомненно, вы хорошо знакомы с принципами работы форм HTML. Как правило, 
      пользователь заполняет в форме одно или несколько полей (например, имя и 
      адрес электронной почты), нажимает кнопку отправки данных, после чего 
      получает ответное сообщение.</P>
      <P>Возможно, вы полагаете, что сбор пользовательских данных в формах HTML 
      — процесс сложный и утомительный. В действительности эта задача решается 
      на удивление просто.</P>
      <P><A href="http.html://doks.gorodok.net/0" name=b></A>Общие сведения о 
      формах</P>
      <P>При вводе данных в форму используются различные управляющие элементы. В 
      одних элементах пользователь вводит информацию с клавиатуры, в других он 
      выбирает нужный вариант, щелкая кнопкой мыши. В формах могут 
      присутствовать скрытые поля, которые поддерживаются самой формой; 
      содержимое скрытых полей не должно изменяться пользователем.</P>
      <P>Одна страница может содержать несколько форм, поэтому необходимы 
      средства, которые позволяли бы отличить одну форму от другой. Более того, 
      вы должны как-то сообщить форме, куда следует перейти, когда пользователь 
      выполняет действие с формой (как правило, нажимает кнопку отправки 
      данных). Обе задачи решаются заключением форм в следующие теги HTML:</P>
      <P>&lt;form action = действие method = "метод" - элементы формы 
      -&lt;/form&gt;</P>
      <P>Как видно из приведенного фрагмента, в тегах форм указываются два 
      важных элемента: действие и метод. Действие указывает, какой сценарий 
      должен обрабатывать форму, а метод определяет способ передачи данных этому 
      сценарию. Существует два метода:</P>
      <UL>
        <LI>Метод get передает все данные формы в конце URL. Из-за различных 
        ограничений, связанных со спецификой языков и длиной данных, этот метод 
        применяется редко. 
        <LI>Метод post передает все данные формы в теле запроса. Этот метод 
        используется чаще, чем get. </LI></UL>
      <P>В этой главе приведена лишь очень краткая вводная информация по 
      основному син-таксису форм HTML. Более полную информацию можно найти в 
      книге А. Хоумера и К. Улмена «Dynamic HTML. Справочник» (СПб.: Питер, 
      1999).</P>
      <P><A name=c></A>Элементы форм, ориентированные на ввод с клавиатуры</P>
      <P>Наше знакомство с построением форм начнется с элементов, 
      ориентированных на ввод с клавиатуры. Таких элементов всего два — 
      текстовое поле (text box) и текстовая область (text area).</P>
      <P>Текстовое поле</P>
      <P>В текстовых полях обычно вводится короткая текстовая информация — 
      скажем, адрес электронной почты, почтовый адрес или имя. Синтаксис 
      определения текстового поля:</P>
      <P>&lt;input type="text" nате="имя_переменной" size="N" maxlength="N" 
      value=""&gt;</P>
      <P>Определение текстового поля включает пять атрибутов:</P>
      <UL>
        <LI>type — тип элемента (для текстовых полей — text); 
        <LI>name — имя переменной, в которой сохраняются введенные данные; 
        <LI>size — общий размер текстового поля в браузере; 
        <LI>maxlength — максимальное количество символов, вводимых в текстовом 
        поле; 
        <LI>value — значение, отображаемое в текстовом поле по умолчанию. 
      </LI></UL>
      <P>Текстовое поле изображено на рис. 10.1.</P>
      <P><IMG src="2_1_10.1Rus.jpg"></P>
      <P>Рис. 10.1. Текстовое поле</P>
      <P>Особой разновидностью текстовых полей является поле для ввода паролей. 
      Оно работает точно так же, как обычное текстовое поле, однако вводимые 
      символы заменяются звездочками. Чтобы создать в форме поле для ввода 
      паролей, достаточно указать type="password" вместо type="text".</P>
      <P>Текстовая область</P>
      <P>Текстовая область (text area) используется для ввода несколько больших 
      объемов текста, не ограничивающихся простым именем или адресом электронной 
      почты. Синтаксис определения текстовой области:</P>
      <P>&lt;textarea name="имя_переменной" rows="N" cols="N" 
      value=""&gt;&lt;/textarea&gt;</P>
      <P>Определение текстового поля включает три атрибута:</P>
      <UL>
        <LI>name — имя переменной, в которой сохраняются введенные данные; 
        <LI>rows — количество строк в текстовой области; 
        <LI>cols — количество столбцов в текстовой области. </LI></UL>
      <P>Текстовая область изображена на рис. 10.2.</P>
      <P>&nbsp;<IMG src="2_1_10.2Rus.jpg"></P>
      <P>Рис. 10.2. Текстовая область</P>
      <P><A name=d></A>Элементы форм, ориентированные на ввод с мыши</P>
      <P>В других элементах форм пользователь выбирает один из заранее 
      определенных вариантов при помощи мыши. Я ограничусь описанием флажков, 
      переключателей и раскрывающихся списков.</P>
      <P>Флажок</P>
      <P>Флажки (checkboxes) используются в ситуациях, когда пользователь 
      выбирает один или несколько вариантов из готового набора — по аналогии с 
      тем, как ставятся «галочки» в анкетах. Синтаксис определения флажка:</P>
      <P>&lt;input type="checkbox" name="имя_переменной" 
      valuе="начальное_значение"&gt;</P>
      <P>Определение флажка включает три атрибута:</P>
      <UL>
        <LI>type — тип элемента (для флажков — checkbox); 
        <LI>name — имя переменной, в которой сохраняются введенные данные (в 
        данном случае — состояние элемента); 
        <LI>value — значение, присваиваемое переменной по умолчанию. Если флажок 
        установлен, именно это значение будет присвоено переменной с указанным 
        именем. Если флажок не установлен, значение атрибута value не 
        используется. </LI></UL>
      <P>Флажок изображен на рис. 10.3.</P>
      <P><IMG src="2_1_10.3Rus.jpg"></P>
      <P>Рис. 10.3. Флажок</P>
      <P>Переключатель</P>
      <P>Переключатель (radio button) представляет собой разновидность флажка; 
      он работает практически так же за одним исключением — в любой момент 
      времени в группе может быть установлен лишь один переключатель. Синтаксис 
      определения переключателя:</P>
      <P>&lt;input type="radio" name="имя_переменной" 
      value="начальное_значение"&gt;</P>
      <P>Как видите, синтаксис почти не отличается от определения флажка. 
      Определение переключателя поля включает три атрибута:</P>
      <UL>
        <LI>type — тип элемента (для переключателей — radio); 
        <LI>name — имя переменной, в которой сохраняются введенные данные (в 
        данном случае — состояние элемента); 
        <LI>value — значение, присваиваемое переменной по умолчанию. Если 
        переключатель установлен, именно это значение будет присвоено переменной 
        с указанным именем. Если флажок не установлен, значение атрибута value 
        не используется. </LI></UL>
      <P>Переключатель изображен на рис. 10.4.</P>
      <P><IMG src="2_1_10.4Rus.jpg"></P>
      <P>Рис. 10.4. Переключатель</P>
      <P>Раскрывающийся список</P>
      <P>Раскрывающиеся списки особенно удобны в ситуации, когда у вас имеется 
      длинный перечень допустимых вариантов, из которого пользователь должен 
      выбрать один вариант. Как правило, раскрывающиеся списки применяются при 
      работе с относительно большими наборами данных — например, при 
      перечислении американских штатов или стран. Синтаксис определения 
      раскрывающегося списка:</P>
      <P>&lt;select name="имя_переменной"&gt;</P>
      <P>&lt;option valuе="имя_переменной1 "&gt;</P>
      <P>&lt;option value="имя_переменной2"&gt;</P>
      <P>&lt;option value="имя_переменнойЗ"&gt;</P>
      <P>&lt;option value="имя_переменнойN"&gt;</P>
      <P>&lt;/select&gt;</P>
      <P>Определение переключателя поля включает три атрибута:</P>
      <UL>
        <LI>name — имя переменной, в которой сохраняются введенные данные (в 
        данном случае — строка, выбранная в списке); 
        <LI>value — значение, отображаемое в списке по умолчанию. </LI></UL>
      <P>Раскрывающийся список изображен на рис. 10.5.</P>
      <P>&nbsp;<IMG src="2_1_10.5Rus.jpg"></P>
      <P>Рис. 10.5. Раскрывающийся список</P>
      <P>Скрытые поля</P>
      <P>Скрытые поля не отображаются в браузере и обычно используются для 
      передачи данных между сценариями. Хотя передача в скрытых полях работает 
      вполне нормально, в РНР существует другое, более удобное средство — 
      сеансовые переменные (см. главу 13). Впрочем, скрытые поля также 
      используются в некоторых ситуациях и потому заслуживают упоминания.</P>
      <P>Синтаксис определения скрытого поля практически идентичен синтаксису 
      текстовых полей, отличается только атрибут типа. Поскольку скрытые поля не 
      отображаются в браузере, привести пример на страницах книги невозможно. 
      Синтаксис определения скрытого поля:</P>
      <P>&lt;input type="hidden" name="имя_переменной" 
      value="начальное_значение"&gt;</P>
      <P>Определение скрытого поля включает три атрибута:</P>
      <UL>
        <LI>type — тип элемента (для скрытых полей — hidden); 
        <LI>name — имя переменной, в которой сохраняются скрытые данные; 
        <LI>value — значение, по умолчанию сохраняемое в скрытом поле. </LI></UL>
      <P>Вообще говоря, название этого элемента — скрытое поле — несколько 
      неточно. Хотя скрытые поля не отображаются в браузерах, пользователь может 
      просто выполнить команду View Source и увидеть, какие скрытые значения 
      хранятся в форме.</P>
      <P>Кнопка отправки данных</P>
      <P>Кнопка отправки данных инициирует действие, заданное атрибутом action 
      тега &lt;form&gt;. Синтаксис определения:</P>
      <P>&lt;input type="submit" value="текст_на_кнопке"&gt;</P>
      <P>Определение кнопки включает два атрибута:</P>
      <UL>
        <LI>type — тип элемента (для кнопки отправки данных — submit); 
        <LI>value — текст, по умолчанию отображаемый на кнопке. </LI></UL>
      <P><IMG src="2_1_10.6Rus.jpg"></P>
      <P>Рис. 10.6. Кнопка отправки данных</P>
      <P>Кнопка сброса</P>
      <P>Кнопка сброса отменяет все изменения, внесенные в элементы формы. 
      Обычно никто ею не пользуется, однако кнопки сброса так часто встречаются 
      на формах в Web, что я решил привести ее описание. Синтаксис 
      определения:</P>
      <P>&lt;input type="reset" value=" текст _на_кнопке"&gt;</P>
      <P>Определение кнопки включает два атрибута:</P>
      <UL>
        <LI>type — тип элемента (для кнопки сброса — reset); 
        <LI>value — текст, по умолчанию отображаемый на кнопке. </LI></UL>
      <P>Кнопка сброса выглядит точно так же, как и кнопка отправки данных, если 
      не считать того, что на ней обычно выводится слово «Reset» (рис. 
10.6).</P>
      <P>Джейкоб Нильсен (Jakob Nielsen), известный авторитет в области Web, 
      недавно напи-сал интересную статью о проблемах, связанных с использованием 
      кнопки сброса. Статья опубликована по адресу <A 
      href="http.html://www.useit.com/alertbox/20000416.html">http://www.useit.com/alertbox/20000416.html</A>.</P>
      <P><A name=e></A>Все вместе: пример формы</P>
      <P>От описания базовых компонентов форм мы переходим к практическому 
      примеру — построению формы для обработки данных, введенных пользователем. 
      Допустим, вы хотите создать форму, в которой пользователь может высказать 
      мнение о вашем Сайте. Пример такой формы приведен в листинге 10.1.</P>
      <P>Листинг 10.1. Пример формы для сбора данных</P>
      <P>&lt;form action = "process.php" method = "post"&gt;</P>
      <P>&lt;b&gt;Please take a moment to tell us what you think about our 
      site:&lt;/b&gt;&lt;p&gt;</P>
      <P>&lt;b&gt;Name:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;input type="text" name="name" size="15" maxlength="25" 
      value=""&gt;&lt;br&gt;</P>
      <P>&lt;b&gt;Email:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;input type="text" name="email" size="15" maxlength="45" 
      value=""&gt;&lt;br&gt;</P>
      <P>&lt;b&gt;How frequently do you visit our site?:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;select name="frequency"&gt;</P>
      <P>&lt;option value=""&gt;Site frequency:</P>
      <P>&lt;option value="0"&gt;This is my first time</P>
      <P>&lt;option value="l"&gt;&amp;lt; 1 time a month</P>
      <P>&lt;option value="2"&gt;Roughly once a month</P>
      <P>&lt;option value="3"&gt;Several times a week</P>
      <P>&lt;option value="4"&gt;Every day</P>
      <P>&lt;option va1ue-"5"&gt;I'm addicted</P>
      <P>&lt;/select&gt;&lt;br&gt;</P>
      <P>&lt;b&gt;I frequently purchase the following products from our 
      site:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;input type="checkbox" name="software" 
      value="software"&gt;Software&lt;br&gt;</P>
      <P>&lt;input type="checkbox" name="cookware" 
      value="cookware"&gt;Cookware&lt;br&gt;</P>
      <P>&lt;input type="checkbox" name="hats" value="hats"&gt;Chef's 
      Hats&lt;br&gt;</P>
      <P>&lt;b&gt;0ur site's greatest asset is:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;input type="radio" name="asset" value="products"&gt;Product 
      selection&lt;br&gt;</P>
      <P>&lt;input type="radio" name="asset" value="design"&gt;Cool 
      design&lt;br&gt;</P>
      <P>&lt;input type="radio" name="asset" value="service"&gt;Customer 
      Service&lt;br&gt;</P>
      <P>&lt;b&gt;Comments:&lt;/b&gt;&lt;br&gt;</P>
      <P>&lt;textarea name="comments" rows="3" 
      cols="40"&gt;&lt;/textarea&gt;&lt;br&gt;</P>
      <P>&lt;input type="submit" value="Submit!"&gt;</P>
      <P>&lt;/form&gt;</P>
      <P>Внешний вид формы в браузере изображен на рис. 10.7.</P>
      <P>&nbsp;<IMG src="2_1_10.7Rus.jpg"></P>
      <P>Рис. 10.7. Пример формы для ввода данных</P>
      <P>Вроде бы все понятно. Возникает вопрос — как получить данные, введенные 
      пользователем, и сделать с ними что-нибудь полезное? Этой теме посвящен 
      следующий раздел, «Формы и РНР».</P>
      <P>Не забывайте: все сказанное ранее — не более чем вводный курс. 
      Приведенная информация ни в коем случае не исчерпывает всех возможностей, 
      предоставляемых различными компонентами форм. За дополнительной 
      информацией обращайтесь к многочисленным учебникам по работе с формами, 
      опубликованным в Web, а также книгам по HTML.</P>
      <P>От предварительного знакомства с формами HTML мы переходим к самому 
      интересному — применению РНР для обработки данных, введенных пользователем 
      в форме.</P>
      <P><A name=f></A>Формы и РНР</P>
      <P>Обработка данных в формах имеет много общего с обработкой переменных, 
      передаваемых в URL, — эта тема подробно рассматривалась в предыдущей 
      главе.</P>
      <P><A name=g></A>Вводные примеры</P>
      <P>Следующие практические примеры помогут вам быстрее освоить различные 
      аспекты обработки форм в РНР. В этих примерах продемонстрированы разные 
      подходы к реализации интерактивных возможностей на сайте.</P>
      <P>Пример 1: передача данных формы из одного сценария в другой</P>
      <P>В первом примере представлена характерная ситуация — когда 
      пользовательские данные вводятся на одной странице и отображаются на 
      другой. В листинге 10.2 приведен код формы для ввода имени пользователя и 
      адреса электронной почты. Когда пользователь щелкает на кнопке отправки 
      данных (кнопка Go!), форма обращается к странице, приведенной в листинге 
      10.3. В свою очередь, листинг 10.3 выводит переменные $name и $mail, 
      переданные с запросом.</P>
      <P>Листинг 10.2. Простая форма</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-2&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;form action="listingl0-3.php" method="post"&gt;</P>
      <P>&lt;b&gt;Give us some information!&lt;/b&gt;&lt;br&gt;</P>
      <P>Your Name:&lt;br&gt;</P>
      <P>&lt;input type="text" name="name" size="20" maxlength="20" 
      value=""&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type="text" name="email" size="20" maxlength="40" 
      value=""&gt;&lt;br&gt;</P>
      <P>&lt;input type="submit" value="go!"&gt;</P>
      <P>&lt;/form&gt;</P>
      <P>&lt;/body&gt; &lt;/html&gt;</P>
      <P>Листинг 10.3. Отображение данных, введенных в листинге 10.1</P>
      <P>&lt;html&gt; &lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-3&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;?</P>
      <P>// Вывести имя и адрес электронной почты.</P>
      <P>print "Hi. $name!. Your email address is $email";</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt; &lt;/html&gt;</P>
      <P>В общих чертах происходит следующее: пользователь заполняет поля формы 
      и нажимает кнопку отправки данных. Управление передается странице, 
      приведенной в листинге 10.3, где происходит форматирование и последующее 
      отображение данных. Как видите, все просто.</P>
      <P>Существует и другой способ обработки данных форм, при котором 
      используется всего один сценарий. К недостаткам этого способа относятся 
      увеличение сценария и как следствие — затруднения с редактированием и 
      сопровождением. Впрочем, есть и достоинства — уменьшение количества 
      файлов, с которыми вам приходится работать. Более того, в этом варианте 
      сокращается избыточный код при проверке ошибок (эта тема рассматривается 
      ниже в данной главе). Конечно, в некоторых ситуациях работать с одним 
      сценарием неудобно, но, по крайней мере, вы должны знать об этой 
      возможности. В примере 2 воспроизводится пример 1, но с использованием 
      лишь одного сценария.</P>
      <P>Пример 2: альтернативная обработка формы (с одним сценарием)</P>
      <P>Обработка данных формы в одном сценарии реализуется относительно 
      просто. Вы проверяете, были ли присвоены значения переменным формы. Если 
      значения присвоены, сценарий обрабатывает их (в нашем примере — просто 
      выводит), а если нет — отображает форму. Решение о том, было ли задано 
      значение переменной или нет, принимается при помощи функции strcmp( ), 
      описанной в главе 8. Пример реализации формы с одним сценарием приведен в 
      листинге 10.4. Обратите внимание: атрибут action формы ссылается на ту же 
      страницу, в которой определяется сама форма. Условная команда i f 
      проверяет состояние переменной скрытого поля с именем $seenform. Если 
      значение $seenform не задано, форма отображается в браузере, а если задано 
      — значит, форма была заполнена пользователем и введенные данные 
      обрабатываются сценарием (в данном примере — просто выводятся в 
      браузере).</P>
      <P>Листинг 10.4. Ввод данных на форме в одном сценарии</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-4&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="f808040"&gt;</P>
      <P>&lt;?</P>
      <P>// Все кавычки внутри $form должны экранироваться,</P>
      <P>// в противном случае произойдет ошибка.</P>
      <P>$form = "</P>
      <P>&lt;form action=\"listing10-4.php\" method=\"post\"&gt;</P>
      <P>&lt;input type=\"hidden\" name=\"seenform\" value=\"y\"&gt;</P>
      <P>&lt;b&gt;Give us some information!&lt;/b&gt;&lt;br&gt;</P>
      <P>Your Name:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"email\" size=\"20\" maxlength=\"40\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>&lt;input type=\"submit\" value=\"subscribe!\"&gt;</P>
      <P>&lt;/form&gt;";</P>
      <P>// Если форма ранее не отображалась, отобразить ее.</P>
      <P>// Для проверки используется значение скрытой переменной $seenform.</P>
      <P>if ($seenform != "у"):</P>
      <P>print "$form";</P>
      <P>else :</P>
      <P>print "Hi. $name!. Your email address is $email";</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>Учтите, что этот вариант создает определенные неудобства, поскольку при 
      повторной загрузке страницы пользователь ничего не узнает о том, правильно 
      ли были заполнены поля формы. Процедура проверки ошибок рассматривается 
      далее в этой главе, а пока достаточно запомнить, что ввод данных можно 
      осуществить при помощи одного сценария.</P>
      <P>Теперь, когда вы представляете, как просто выполняются операции с 
      формами, мы переходим к интересному примеру — автоматической отправке 
      данных пользователя по заданному адресу электронной почты. Эта возможность 
      реализована в примере 3.</P>
      <P>Пример 3: автоматическая отправка данных по электронной почте</P>
      <P>Вывести пользовательские данные в браузере несложно, но вряд ли это 
      можно назвать содержательной обработкой пользовательского ввода. Один из 
      способов обработки информации заключается в ее отправке по электронной 
      почте — например, администратору сайта. Хотя при помощи гиперссылки 
      mailto: можно отправить сообщение прямо из браузера, следует учитывать, 
      что внешние приложения электронной почты настроены не на каждом 
      компьютере. Следовательно, отправка сообщений с web-формы более надежно 
      гарантирует, что сообщение будет доставлено адресату.</P>
      <P>В следующем разделе, mail( ), создается небольшая форма, в которой 
      пользователь вводит информацию и комментарии по поводу сайта. Затем данные 
      форматируются соответствующим образом и передаются стандартной функции РНР 
      mail( ). Но прежде чем переходить к построению формы, необходимо 
      предварительно рассмотреть синтаксис функции mail( ).</P>
      <P>mail ( )</P>
      <P>Функция mail( ) отправляет сообщение заданному адресату по электронной 
      почте. Синтаксис функции mail( ):</P>
      <P>boolean mail (string получатель, string тема, string сообщение [, 
      string доп_заголовки])</P>
      <P>В параметре тема, как нетрудно предположить, передается тема сообщения. 
      Параметр сообщение содержит текст сообщения, а необязательный параметр 
      доп_за головки предназначен для включения дополнительной информации 
      (например, атрибутов форматирования HTML), пересылаемой с сообщением.</P>
      <P>В системе UNIX функция mail( ) использует утилиту sendmail. В Windows 
      эта функция работает лишь при наличии установленного почтового сервера или 
      если функция mail( ) связана с работающим сервером SMTP. Эта задача 
      решается модификацией переменной SMTP в файле php.ini.</P>
      <P>Если вы сделали все необходимое и функция mail( ) работает в вашей 
      системе, попробуйте выполнить следующий фрагмент (конечно, адрес 
      youraddress@yourserver.com заменяется вашим настоящим адресом электронной 
      почты):</P>
      <P>$email = "youraddress@yourserver.com";</P>
      <P>$subject = "This is the subject";</P>
      <P>$message = "This is the message";</P>
      <P>$headers = "From: somebody@somesite.com";</P>
      <P>mail ($email, $subject, $message, $headers);</P>
      <P>Хотя при обширной переписке, конечно, следует использовать 
      специализированные почтовые программы вроде majordomo (<A 
      href="http.html://www.greatcircle.com/majordomo">http://www.greatcircle.com/majordomo</A>), 
      в простых случаях функции РНР mail( ) оказывается вполне достаточно.</P>
      <P>Итак, после знакомства с функцией mail( ) можно применить ее на 
      практике. В листинге 10.5 показано, как получить информацию от 
      пользователя и отправить ее по адресу, заданному администратором 
      сценария.</P>
      <P>Листинг 10.5. Пересылка пользовательских данных функцией mail( )</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-5&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>// Все кавычки внутри $form должны экранироваться.</P>
      <P>// в противном случае произойдет ошибка.</P>
      <P>$form = "</P>
      <P>&lt;form action=\"listing10-5.php\" method=\"post\"&gt;</P>
      <P>&lt;input type=\"hidden\" name=\"seenform\" value=\"y\"&gt;</P>
      <P>&lt;b&gt;Send us your comments!&lt;/b&gt;&lt;br&gt;</P>
      <P>Your Name:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name-\"email\" size=\"20\" maxlength=\"40\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>Your Comments:&lt;br&gt;</P>
      <P>&lt;textarea name=\"comments\" rows=\"3\" 
      cols=\"30\"&gt;&lt;/textarea&gt;&lt;br&gt;</P>
      <P>&lt;input type=\"submit\" value=\"submit!\"&gt;</P>
      <P>&lt;/form&gt;</P>
      <P>// Если форма ранее не отображалась, отобразить ее.</P>
      <P>// Для проверки используется значение скрытой переменной $seenform.</P>
      <P>if ($seenform != "у") :</P>
      <P>print "$form"; else :</P>
      <P>// Переменная $recipient определяет получателя данных формы</P>
      <P>$recipient = "yourname@youremail.com";</P>
      <P>// Тема сообщения</P>
      <P>$subject = "User Comments ($name)";</P>
      <P>// Дополнительные заголовки $headers = "From: $email";</P>
      <P>// Отправить сообщение или выдать сообщение об ошибке</P>
      <P>mail($recipient, $subject, $comments, $headers) or die("Could not send 
      email!");</P>
      <P>// Вывести сообщение для пользователя</P>
      <P>print "Thank you $name for taking a moment to send us your 
      comments!";</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>Неплохо, правда? Листинг 10.5 работает так же, как листинг 10.4; 
      сначала мы проверяем, отображалась ли форма ранее. Если это происходило, 
      программа вызывает функцию mail( ) и пользовательские данные отправляются 
      по адресу, определяемому переменной $recipient. Затем в браузере выводится 
      благодарственное сообщение для пользователя.</P>
      <P>Простейшим расширением этого примера будет отправка благодарственного 
      сообщения по электронной почте (вторым вызовом mail( )). Следующий пример 
      развивает эту идею — пользователю предлагается на выбор несколько 
      бюллетеней. Выбранные бюллетени отправляются по электронной почте.</P>
      <P>Пример 4: отправка запрашиваемой информации по электронной почте</P>
      <P>В этом примере в форме создается несколько флажков, каждый из которых 
      соответствует отдельному документу с информацией о сайте. Пользователь 
      устанавливает один, два или три флажка, вводит свой адрес, и запрашиваемые 
      брошюры отправляются ему по электронной почте. Обратите внимание на 
      применение массива при работе с флажками — это упрощает проверку выбранных 
      флажков, а также улучшает структуру программы.</P>
      <P>Информационные сообщения хранятся в отдельных файлах. В нашем примере 
      используются три текстовых файла:</P>
      <UL>
        <LI>site.txt — информация о сайте; 
        <LI>team.txt — информация о талантливых разработчиках сайта; 
        <LI>events.txt — приглашение на очередное мероприятие. </LI></UL>
      <P>Исходный текст примера приведен в листинге 10.6.</P>
      <P>Листинг 10.6.Отправка информации, запрашиваемой пользователем</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing10-5&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;?</P>
      <P>$form = "</P>
      <P>&lt;form action=\"Listing10-6.php\" method=\"post\"&gt;</P>
      <P>&lt;input type=\"hidden\" name=\"seenform\" value=\"y\"&gt;</P>
      <P>&lt;b&gt;Receive information about our site!&lt;/b&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"email\" size=\"20\" maxlength=\"40\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>&lt;input type=\"checkbox\" name=\"information[site]\" 
      value=\"y\"&gt;Site Architecture&lt;br&gt;</P>
      <P>&lt;input type=\"checkbox\" name=\"information[team]\" 
      value=\"y\"&gt;Development Team&lt;br&gt;</P>
      <P>&lt;input type=\"checkbox\" name=\"information[events]\" 
      value=\"y\"&gt;Upcoming Events&lt;br&gt;</P>
      <P>&lt;input type=\"submit\" value=\"send it to me!\"&gt;</P>
      <P>&lt;/form&gt;":</P>
      <P>if ($seenform != "y") :</P>
      <P>print "$form"; else :</P>
      <P>$headers = "From: devteam@yoursite.com";</P>
      <P>// Перебрать все пары "ключ/значение"</P>
      <P>while ( list($key, Sval) = each ($information) ) :</P>
      <P>// Сравнить текущее значение с "у" if ($val == "у") :</P>
      <P>// Построить имя файла, соответствующее текущему ключу</P>
      <P>$filename = "$key.txt":</P>
      <P>$subject = "Requested $key information";</P>
      <P>// Открыть файл</P>
      <P>$fd = fopen ($filename, "r");</P>
      <P>// Прочитать содержимое всего файла в переменную $contents = fread 
      ($fd. filesize ($filename));</P>
      <P>// Отправить сообщение</P>
      <P>mail($email, $subject, $contents, $headers) or die("Can't send 
      email!");; fclose($fd);</P>
      <P>endif;</P>
      <P>endwhile;</P>
      <P>// Известить пользователя об успешной отправке</P>
      <P>print sizeof($information)." informational newsletters</P>
      <P>have been sent to $email!";</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>В листинге 10.6 мы перебираем пары «ключ/значение» в цикле while и 
      отправляем только те бюллетени, у которых значение равно у. Следует 
      помнить, что имена текстовых файлов должны соответствовать ключам 
      массива</P>
      <P>(site.txt, team.txt и events.txt). Имя файла строится динамически по 
      ключу, после чего файл открывается по имени и его содержимое загружается в 
      переменную ($contents). Затем переменная $contents передается функции 
      mail( ) в качестве параметра.</P>
      <P>В следующем примере пользовательские данные сохраняются в текстовом 
      файле.</P>
      <P>Пример 5: сохранение пользовательских данных в текстовом файле</P>
      <P>Пользовательские данные сохраняются в текстовом файле для последующего 
      статистического анализа, поиска и т. д. — короче, любой обработки по 
      вашему усмотрению. В листинге 10.7, как и в предыдущих примерах, данные 
      формы обрабатываются в одном сценарии. Пользователю предлагается ввести 
      четыре объекта данных: имя, адрес электронной почты, язык и профессию. 
      Введенная информация сохраняется в текстовом файле user_information.txt. 
      Элементы данных разделяются символами «вертикальная черта» (|).</P>
      <P>Листинг 10.7. Сохранение пользовательской информации в текстовом 
      файле</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;titlexisting 10-7&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;?</P>
      <P>// Создать форму</P>
      <P>$form = "</P>
      <P>&lt;form action=\"Listing10-7.php\" method=\"post\"&gt;</P>
      <P>&lt;input type=\"hidden\" name=\"seenform\" value=\"y\"&gt;</P>
      <P>&lt;b&gt;Give us your personal info!&lt;/fb&gt;&lt;br&gt;</P>
      <P>Your Name:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name"=\"email\" size=\"20\" maxlength=\"20\" 
      value=\"\"&gt;&lt;br&gt;</P>
      <P>Your Preferred Language:&lt;br&gt;</P>
      <P>&lt;select name=\"language\"&gt;</P>
      <P>&lt;option value=\"\"&gt;Choose a language:</P>
      <P>&lt;option value=\"English\"&gt;English</P>
      <P>&lt;option value=\"Spanish\"&gt;Spanish</P>
      <P>&lt;option value=\"Italian\"&gt;Italian</P>
      <P>&lt;option value=\"French\"&gt;French</P>
      <P>&lt;option value=\"Japanese\"&gt;Japanese</P>
      <P>&lt;option value=\"newyork\"&gt;NewYork-ese</P>
      <P>&lt;/select&gt;&lt;br&gt;</P>
      <P>Your Occupation:'"ibr&gt;</P>
      <P>&lt;select name=\"job\"&gt;</P>
      <P>&lt;option value=\"\"&gt;What do you do?:</P>
      <P>&lt;option value=\"student\"&gt;Student</P>
      <P>&lt;option value=\ "programmed "&gt;Programmer</P>
      <P>&lt;option value=\"manager\"&gt;Project Manager</P>
      <P>&lt;option value=\"slacker\"&gt;Slacker</P>
      <P>&lt;option value=\"chef\"&gt;Gourmet Chef</P>
      <P>&lt;/select&gt;&lt;br&gt;</P>
      <P>&lt;input type=\"submit\" value=\"submit!\"&gt;</P>
      <P>&lt;/form&gt;";</P>
      <P>// Заполнялась ли форма ранее? if ($seenform != "у") :</P>
      <P>print "$form"; else :</P>
      <P>$fd = fopen("useMnformation.txt", "a");</P>
      <P>// Убедиться, что во введенных данных не встречается</P>
      <P>// вертикальная черта.</P>
      <P>$name = str_replace("|", "", $name);</P>
      <P>$email = str_replace("|", "", $email);</P>
      <P>// Построить строку с пользовательскими данными</P>
      <P>$user_row = $name." ".$email."|".$language." ".$job."\n";</P>
      <P>fwrite($fd, $user_row) or die("Could not write to file!");</P>
      <P>fclose($fd);</P>
      <P>print "Thank you for taking a moment to fill out our brief 
      questionnaire!":</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>Обратите внимание на фрагмент, в котором мы проверяем, что пользователь 
      не включил в имя или адрес электронной почты символы «вертикальная черта» 
      (|). Функция str_replace( ) удаляет эти символы, заменяя их пустой 
      строкой. Если бы это не было сделано, пользовательские символы | нарушили 
      бы структуру файла данных и существенно затруднили (а то и сделали 
      невозможным) его правильную обработку.</P>
      <P>При работе с относительно малыми объемами информации вполне можно 
      обойтись текстовыми файлами. Однако при большом количестве пользователей 
      или объеме сохраняемой информации для хранения и обработки данных, 
      введенных в форме, лучше воспользоваться базой данных. Эта тема подробно 
      рассматривается в главе 11.</P>
      <P>До настоящего момента предполагалось, что пользователь всегда вводит 
      правильные данные и не действует злонамеренно. В высшей степени 
      оптимистичное предположение! В следующем разделе мы усовершенствуем 
      рассмотренные примеры и организуем проверку целостности данных форм. 
      Проверка ошибок не только обеспечивает удаление неполной и неправильной 
      информации, но и обеспечивает более эффективный и удобный интерфейс.</P>
      <P><A name=h></A>Проверка ошибок</P>
      <P>Обработка пользовательских данных дает осмысленный результат лишь в том 
      случае, если данные имеют правильную структуру. Проверить достоверность 
      введенных данных невозможно, однако вы можете проверить их целостность 
      (например, убедиться в том, что адрес электронной почты соответствует 
      стандартному шаблону). Хотя для проверки данных часто применяется 
      технология JavaScript, могут возникнуть проблемы с несовместимостью 
      браузеров. Поскольку код РНР выполняется на стороне сервера, вы всегда 
      можете быть уверены в том, что проверка данных формы даст нужный результат 
      (конечно, при условии правильности вашей программы).</P>
      <P>При обнаружении ошибки в данных необходимо сообщить об этом 
      пользователю и предложить внести исправления. Существует несколько 
      возможных решений, в том числе простой вывод сообщения об ошибке и 
      предложение альтернативных вариантов (например, если пользователь выбирает 
      имя, которое уже было выбрано другим пользователем). В этом разделе 
      рассматривается процедура проверки и вывода сообщений,</P>
      <P>Пример 6: вывод информации о пустых или ошибочно заполненных полях 
      формы</P>
      <P>Ни один разработчик сайта не захочет раздражать пользователя 
      невразумительными сообщениями об ошибках в данных — особенно если 
      пользователь запрашивает дополнительную информацию о товаре или оформляет 
      покупку! Чтобы пользователь понял, какие поля формы остались пустыми или 
      были заполнены неверно, сообщения должны быть четкими и конкретными.</P>
      <P>Мы последовательно проверяем все поля формы и убеждаемся в том, что они 
      не остались пустыми. Там, где это возможно, проверяется правильность 
      структуры введенных данных. Если проверка прошла успешно, мы переходим к 
      следующему полю; в противном случае программа выводит сообщение об ошибке, 
      устанавливает флаг, который позднее используется для повторного 
      отображения формы, и переходит к следующему полю. Процедура повторяется до 
      тех пор, пока не будут проверены все поля формы (листинг 10.8).</P>
      <P>Листинг 10.8. Проверка данных формы и вывод сообщений об ошибках</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-8&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#cbda74" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;?</P>
      <P>// Создать форму</P>
      <P>$form = "</P>
      <P>&lt;form action=\"Listing10-8.php\" method=\"post\"&gt;</P>
      <P>&lt;input type=\"hidden\" name=\"seenform\" value=\"y\"&gt;</P>
      <P>&lt;b&gt;Give us some information!&lt;/b&gt;&lt;br&gt;</P>
      <P>Your Name:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"name\" size=\"20\" maxlength=\"20\" 
      value=\"$name\"&gt;&lt;br&gt;</P>
      <P>Your Email:&lt;br&gt;</P>
      <P>&lt;input type=\"text\" name=\"email\" s1ze=\"20\" maxlength=\"40\" 
      value=\"$email\"&gt;&lt;br&gt;</P>
      <P>&lt;input type=\"submit\" value=\"subscribe!\"&gt;</P>
      <P>&lt;/form&gt;":</P>
      <P>// Заполнялась ли форма ранее?</P>
      <P>if ($seenform != "у"):</P>
      <P>print "$form";</P>
      <P>// Пользователь заполнил форму. Проверить введенные данные, else :</P>
      <P>$error_flag = "n";</P>
      <P>// Убедиться в том. что поле имени содержит информацию</P>
      <P>if ($name == "") :</P>
      <P>print "&lt;font color=\"red\"&gt;* You forgot to enter your name!</P>
      <P>&lt;/font&gt; &lt;br&gt;":</P>
      <P>$error_flag = "y";</P>
      <P>endif:</P>
      <P>// Убедиться в том. что поле адреса содержит информацию</P>
      <P>if ($email == "") :</P>
      <P>else :</P>
      <P>print "&lt;font color=\"red\"&gt;* You forgot to enter your email !</P>
      <P>&lt;/font&gt; &lt;br&gt;"</P>
      <P>$error_flag = "y";</P>
      <P>// Преобразовать все алфавитные символы в адресе</P>
      <P>// электронной почты к нижнему регистру</P>
      <P>$email = strtolower(trim($email)):</P>
      <P>// Убедиться в правильности синтаксиса</P>
      <P>// адреса электронной почты</P>
      <P>if (! @eregi('^[0-9a-z]+'.</P>
      <P>'([0-9a-z-]+\.)+'.</P>
      <P>'([0-9a-z]){2.4}$'. $email)) :</P>
      <P>print "&lt;font color=\"red\"&gt;* You entered an invalid email 
      address!</P>
      <P>&lt;/font&gt; &lt;br&gt;" :</P>
      <P>$error_flag = "y";</P>
      <P>endif;</P>
      <P>endif;</P>
      <P>// Если флаг ошибки $error_flag установлен.</P>
      <P>// заново отобразить форму</P>
      <P>if ($error_flag == "у") : print "$form";</P>
      <P>else :</P>
      <P>// Обработать данные пользователя</P>
      <P>print "You entered valid form information!";</P>
      <P>endif;</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>Программа в листинге 10.8 убеждается в том, что поля имени и адреса 
      электронной почты не остались пустыми, а также проверяет правильность 
      синтаксиса вве-, денного адреса. Если в результате каких-либо проверок в 
      форме обнаруживаются ошибки, программа выводит соответствующие сообщения и 
      отображает форму заново — при этом вся введенная ранее информация остается 
      в форме, благодаря чему пользователю будет проще внести исправления. Если 
      вывести пустую форму и предложить пользователю заполнить ее заново, он 
      может отправиться</P>
      <P>за необходимым товаром или услугой в другое место.</P>
      <P><A name=i></A>Динамическое конструирование форм</P>
      <P>До настоящего момента я программировал все формы вручную. Любому 
      программисту известно, что ручное кодирование — это плохо, поскольку оно 
      увеличивает вероятность ошибок, не говоря уже о лишних затратах 
      времени.</P>
      <P>В следующем разделе я представлю сценарий, в котором раскрывающийся 
      список строится динамически по содержимому массива. Этот прием несложен, 
      однако</P>
      <P>он экономит немало времени как при исходном программировании, так и при 
      последующем сопровождении программы.</P>
      <P>Пример 7: построение раскрывающегося списка</P>
      <P>Предположим, у вас имеется список сайтов, которые вы хотите 
      порекомендовать посетителю из-за классного дизайна. Вместо того чтобы 
      жестко кодировать каждую строку списка, можно создать массив и 
      воспользоваться его содержимым для заполнения списка.</P>
      <P>В листинге 10.9, как и в предыдущих примерах, реализован вариант с 
      одним сценарием. Сначала мы проверяем, было ли присвоено значение 
      переменной $site. Если проверка дает положительный результат, вызывается 
      функция header( ) с параметром, в котором значение $site присоединяется к 
      строке «Location:http://». При передаче этой команды функция header О 
      перенаправляет браузер на указанный URL. Если значение переменной $site не 
      задано, форма выводится в браузере. Раскрывающийся список строится в 
      цикле, количество итераций зависит от размера массива Sfavsites. В 
      листинге 10.9 я включил в этот массив пять своих любимых сайтов. Конечно, 
      вы можете добавить в него сколько угодно своих сайтов.</P>
      <P>Запомните одно 
      важное обстоятельство — функция header( ) должна вызываться до вывода 
      данных в браузере. Ее нельзя просто вызвать в любой точке сценария РНР. 
      Несвоевременные вызовы header( ) порождают столько проблем у неопытных 
      программистов РНР, что я рекомендую повторить это правило раз пять, чтобы 
      лучше запомнить его.</P>
      <P>Листинг 10.9. Динамическое построение раскрывающегося списка</P>
      <P>&lt;?</P>
      <P>if ($site != "") :</P>
      <P>header("Location: http://Ssite");</P>
      <P>exit;</P>
      <P>else :</P>
      <P>?&gt;</P>
      <P>&lt;html&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;Listing 10-9&lt;/Fit1e&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" Iink="#cbda74" 
      vlink="#808040" alink="#808040"</P>
      <P>$favsites = array ("www.k10k.com". "www.yahoo.com",</P>
      <P>"www.drudgereport.com",</P>
      <P>"www.phprecipes.com",</P>
      <P>"www.frogdesign.com"):</P>
      <P>// Создать форму</P>
      <P>&lt;?</P>
      <P>&lt;form action = "Listing10-9.php" method="post"&gt;</P>
      <P>&lt;select name="site"&gt;</P>
      <P>&lt;option value = ""&gt;Choose a site:</P>
      <P>$х = 0:</P>
      <P>while ( $х &lt; sizeof ($favsites) ) :</P>
      <P>print "&lt;option value='$favsites[$x]'&gt;$favsites[$x]";</P>
      <P>$x++;</P>
      <P>endwhile;</P>
      <P>?&gt;</P>
      <P>&lt;/select&gt;</P>
      <P>&lt;input type="submit" value="go!"&gt;</P>
      <P>&lt;/form&gt;</P>
      <P>&lt;?</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>Динамическое конструирование форм особенно удобно при обработке больших 
      объемов данных, которые в любой момент могут измениться, что приведет к 
      устареванию всей жестко закодированной информации форм. Впрочем, я 
      рекомендую жестко кодировать все статические данные (например, список 
      штатов США), поскольку это ускорит работу программы.</P>
      <P><A name=j></A>Проект: гостевая книга</P>
      <P>С первых дней World Wide Web разработчики сайтов стремились к тому, 
      чтобы посетители могли поделиться своими мыслями и комментариями по поводу 
      сайта. На сайтах эта возможность обычно называется «гостевой книгой» 
      (guestbook). Я покажу, как легко создать гостевую книгу при помощи форм 
      HTML, средств обработки форм РНР и текстового файла.</P>
      <P>Прежде всего создается инициализационный файл, содержащий некоторые 
      глобальные переменные и функции приложения (листинг 10.10).</P>
      <P>Листинг 10.10. Файл init.inc, используемый при создании гостевой 
      книги</P>
      <P>&lt;?</P>
      <P>// Файл: init.inc</P>
      <P>// Назначение: глобальные переменные и функции для проекта гостевой 
      книги</P>
      <P>// Заголовок страницы по умолчанию</P>
      <P>$title = "My Guestbook";</P>
      <P>// Цвет фона</P>
      <P>$bg_color = "white": /</P>
      <P>// Гарнитура шрифта</P>
      <P>$font_face = "Arial, Verdana, Times New Roman";</P>
      <P>// Цвет шрифта</P>
      <P>$font_color = "black";</P>
      <P>// Дата отправки $post_date - date("M d y");</P>
      <P>// Файл данных гостевой книги</P>
      <P>$guest_file = "comments.txt";</P>
      <P>// Функция читает данные гостевой книги</P>
      <P>//и отображает их в браузере</P>
      <P>function view_guest($guest_file) {</P>
      <P>GLOBAL $font_face, $font_color;</P>
      <P>print "Return to &lt;a 
      href=\"index.php\"&gt;index&lt;/a&gt;,&lt;br&gt;&lt;br&gt;";</P>
      <P>// Если в файле гостевой книги имеются данные...</P>
      <P>if (filesize($guest_file) &gt; 0) :</P>
      <P>// Открыть файл данных гостевой книги</P>
      <P>$fh = fopen($guest_file. "r") or die("Couldn't open $guest_file");</P>
      <P>print "&lt;table border=1 cellpadding=2 cellspacing=0 
      width=\"600\"&gt;";</P>
      <P>// Повторять до конца файла</P>
      <P>while (! feof($fh)) :</P>
      <P>// Прочитать следующую строку</P>
      <P>$line &lt;= fgetsdfh, 4096);</P>
      <P>// Разбить строку на компоненты</P>
      <P>// и присвоить каждый компонент переменной</P>
      <P>list($date. $name, $email, $comments) = explode("|", $line):</P>
      <P>// Если указано имя посетителя, вывести его</P>
      <P>if ($name != "") :</P>
      <P>print "&lt;tr&gt;":</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_co!or\"</P>
      <P>face=\"$font_face\"&gt;Date:&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>face=\"$font_face\"&gt;$date&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;/tr&gt;";</P>
      <P>print "&lt;tr&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>&nbsp;face=\"$font_face\"&gt;Name:&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>&nbsp;face=\"$font_face\"&gt;$name&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;/tr&gt;";</P>
      <P>print "&lt;tr&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>&nbsp;face=\"$font_face\"&gt;Email:&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>&nbsp;face=\"$font_face\"&gt;$email&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;/tr&gt;";</P>
      <P>print "&lt;tr&gt;";</P>
      <P>print "&lt;td valign=\'top\"&gt;&lt;font color=\"$font_color\"</P>
      <P>face=\"$font_face\"&gt;Message:&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;td&gt;&lt;font color=\"$font_color\"</P>
      <P>face=\"$font_face\"&gt;$comments&lt;/font&gt;&lt;/td&gt;";</P>
      <P>print "&lt;/tr&gt;";</P>
      <P>print "&lt;tr&gt;&lt;td 
      colspan=\"2\"&gt;&amp;nbsp:&lt;/td&gt;&lt;/tr&gt;";</P>
      <P>endif;</P>
      <P>endwhile;</P>
      <P>print "&lt;/table&gt;";</P>
      <P>// Закрыть файл</P>
      <P>fclose($fh);</P>
      <P>else :</P>
      <P>print "&lt;h3&gt;Currently there are no entries in the 
      guestbook!&lt;/h3&gt;";</P>
      <P>endif;</P>
      <P>} // view_guest</P>
      <P>// Функция сохраняет новую информацию в файле данных</P>
      <P>function add_guest($name, $email, $comments) {</P>
      <P>GLOBAL $post_date, $guest_file;</P>
      <P>// Отформатировать данные для ввода ,</P>
      <P>$contents = "$post_date|$name|$email |$comments\n";</P>
      <P>// Открыть файл данных</P>
      <P>$fh = fopen($guest_file. "a") or dieC'Could not open 
$guest_file!");</P>
      <P>// Записать данные в файл</P>
      <P>$wr = fwrite($fh, $contents) or die("Could not write to 
      $guest_file!");</P>
      <P>// Закрыть файл fclose($fh);</P>
      <P>} // add_guest</P>
      <P>?&gt;</P>
      <P>Затем создаются еще три файла: файл ссылок index.php, файл 
      add_guest.php для вывода информации гостевой книги и файл view_guest.php 
      для ввода новых данных. Файл index.php (листинг 10.11) просто отображает 
      две ссылки для выполнения основных функций гостевой книги — просмотра и 
      добавления новых данных. Эти ссылки легко включаются в сайт, имеющий более 
      сложную структуру.</P>
      <P>Листинг 10.11. Файл index.php со ссылками для просмотра и добавления 
      новых данных в гостевую книгу</P>
      <P>&lt;html&gt;</P>
      <P>&lt;?</P>
      <P>INCLUDE("init.inc");</P>
      <P>?&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;&lt;?=$page_title;?&gt;&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="&lt;?=$bg_color;?&gt;" text="#000000" link="#808040" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>&lt;a href="view_guest.html.php"&gt;View the 
      guestbook!&lt;/a&gt;&lt;br&gt;</P>
      <P>&lt;a href="add_guest.html.php"&gt;Sign the 
      guestbook!&lt;/a&gt;&lt;br&gt;</P>
      <P>&lt;/body&gt;</P>
      <P>&lt;/html&gt;</P>
      <P>Файл view_guest.php (листинг 10.12) выводит всю информацию гостевой 
      книги, хранящуюся в файле данных.</P>
      <P>Листинг 10.12. Файл view_guest.php</P>
      <P>&lt;html&gt;</P>
      <P>&lt;?</P>
      <P>INCLUDE("init.inc");</P>
      <P>?&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;t1tle&gt;&lt;?=$page_title;?&gt;&lt;/t1tle&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="&lt;?=$bg_color:?&gt;" text="#000000" link=" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>vi ew_guest ( $guest_file );</P>
      <P>?&gt;</P>
      <P>Файл add_guest.php (листинг 10.13) запрашивает у пользователя новые 
      данные для внесения в гостевую книгу. Введенная информация записывается в 
      файл данных.</P>
      <P>Листинг 10.13. Файл add_guest.php</P>
      <P>&lt;html&gt;</P>
      <P>&lt;?</P>
      <P>INCLUDE("init.inc");</P>
      <P>?&gt;</P>
      <P>&lt;head&gt;</P>
      <P>&lt;title&gt;&lt;?=$page_title:?&gt;&lt;/title&gt;</P>
      <P>&lt;/head&gt;</P>
      <P>&lt;body bgcolor="#ffffff" text="#000000" link="#808040" 
      vlink="#808040" alink="#808040"&gt;</P>
      <P>?&lt;</P>
      <P>// Если форма еще не отображалась - запросить данные у пользователя</P>
      <P>if (! $seenform) :</P>
      <P>?&gt;</P>
      <P>&lt;form action="add_guest.php" method="post"&gt;</P>
      <P>&lt;input type="hidden" name="seenform" value="y"&gt;</P>
      <P>Name:&lt;br&gt;</P>
      <P>&lt;input type="text" name="name" size="15" maxlength="30" 
      value=""&gt;&lt;br&gt;</P>
      <P>Email:&lt;br&gt;</P>
      <P>&lt;input type="text" name="email" size="15" maxlength="35" 
      value=""&gt;&lt;br&gt;</P>
      <P>Comment: &lt;br&gt;</P>
      <P>&lt;textarea name="comment" rows="'3" 
      cols="40"&gt;&lt;/textarea&gt;&lt;br&gt;</P>
      <P>&lt;input type="submit" value="submit"&gt;</P>
      <P>&lt;/form&gt;</P>
      <P>// Форма уже отображалась - добавить данные в текстовый файл.</P>
      <P>else :</P>
      <P>add_guest($name, $email, $comment);</P>
      <P>print "&lt;h3&gt;Your comments have been added to the guestbook.</P>
      <P>&lt;a href=\"index.php\"&gt;Click here&lt;/a&gt; to return to the 
      index. &lt;/h3&gt;";</P>
      <P>endif;</P>
      <P>?&gt;</P>
      <P>К числу основных преимуществ модульной разработки приложений относится 
      простота адаптации для других систем. Допустим, вы решили перейти от 
      хранения данных в текстовом файле к использованию базы данных. Стоит 
      изменить содержимое add_guest( ) и view_guest( ), и ваша гостевая книга 
      перейдет на работу с базой данных.</P>
      <P>На рис. 10.8 показано, как выглядит гостевая книга после сохранения 
      пары записей.</P>
      <P>&nbsp;<IMG src="2_1_10.8Rus.jpg"></P>
      <P>Рис. 10.8. Просмотр гостевой книги (view_guest.php)</P>
      <P>Информация, показанная на рис. 10.8, хранится в файле данных в 
      следующем виде:</P>
      <P>Oct 29 00|Michele|michelle@latorre.com|I love cheese!</P>
      <P>Oct 29 00|Nino|nino@latorre.com|Great site!</P>
      <P><A name=k></A>Итоги</P>
      <P>Обработка данных форм принадлежит к числу сильнейших сторон РНР, 
      поскольку простота и надежность сочетаются в ней с одним из важнейших 
      аспектов любого сайта — интерактивностью. В этой главе рассматривался 
      широкий круг вопросов, относящихся к формам и роли РНР в обработке данных 
      форм, в том числе:</P>
      <UL>
        <LI>общие сведения о синтаксисе форм; 
        <LI>передача данных форм между сценариями РНР; 
        <LI>обработка форм в одном сценарии; 
        <LI>функция mail( ); 
        <LI>отправка данных формы по электронной почте; 
        <LI>автоматическая обработка пользовательских запросов на получение 
        информации; 
        <LI>сохранение данных пользователя в текстовом файле; 
        <LI>проверка ошибок; 
        <LI>динамическое конструирование форм. </LI></UL>
      <P>Если вы собираетесь работать со сколько-нибудь заметными объемами 
      информации, одним из первых шагов на этом пути должна стать интеграция 
      базы данных в структуру сайта. Эта тема рассматривается в следующей 
      главе.</P></LI></DIV>
<center>
[ <a href="09.php">Назад</a> | <a href="index.php">Содержание</a> | <a href="11.php">Вперед</a> ]
</center><br>
<? include_once '../../sys/inc/tfoot.php'; ?>