Серверные программные интерфейсы приложений
Серверные программы API (Application Programming Interfaces) можно поверхностно обозначить как сменные модули Web-сервера. Среди распространенных API такие, как ISAPI для сервера IIS от Microsoft, NSAPI для сервера Netscape/I Planet/Sun, Apache Modules для Apache и сервлеты Java для Web-серверов с поддержкой Java. Преимуществом серверных программ API является то, что в целом их плотное взаимодействие с Web-сервером приводит к высокой производительности. Недостатком, вне всяких сомнений, представляется сложность написания такой программы и вероятность того, что ошибочный серверный модуль, на самом деле, может привести к отказу всего сервера.
Сетевые и сопутствующие протоколы
В числе протоколов, составляющих основу Internet, присутствует стек сетевых протоколов TCP/IP. Не единственный протокол, но целая группа таковых, именно TCP/IP делает возможным все службы, существующие в Internet. В отдельности, IP (Internet Protocol, протокол Internet) предоставляет базовую информацию, связанную с адресацией и маршрутизацией, необходимую для доставки данных по сети Internet. С другой стороны, TCP (Transport Control Protocol, протокол управления передачей) обеспечивает средства, делающие коммуникации надежными, такие, как коррекция и повторная передача. Объединив их вместе, в сочетании со службой доменных имен (Domain Name Service, DNS), представляющей собой процесс преобразования полностью определенных доменных имен вроде www.webdesignref.com, в соответствующие им IP-адреса (66.45.42.235), мы получаем возможность создавать в сети Internet службы высокого уровня, такие как электронная почта или Web-сайты. Знание протоколов низкого уровня многим Web-дизайнерам может показаться бессмысленным, однако при разработке в высшей степени масштабируемых Web-сайтов понимание подробностей организации сетей оказывается особенно полезным. Как бы то ни было, независимо от задач сайта, в следующем протоколе, который мы будем обсуждать, должен разбираться каждый Web-дизайнер.
HTTP
HTTP (Hypertext Transport Protocol, протокол передачи ^гипертекста) — это протокол прикладного уровня, отвечающий за взаимодействие между агентом пользователя (которым обычно является Web-браузер) и Web-сервером. Этот простой протокол определяет восемь основных команд (GET, POST, HEAD, PUT, DELETE, OPTIONS, TRACE и CONNECT), которыми агент пользователя может воспользоваться- для запроса или управления данными. В ответах могут содержаться как числовые, так и текстовые коды (к примеру, 404 Not Found) и сопутствующие данные.
Простота протокола HTTP — это одновременно и счастье, и напасть. Его несложно реализовать, однако недостаток управления состоянием и проблемы с производительностью приносят Web-разработчикам неприятности. Спецификация HTTP 1.1, определенная в документе RFC 2616, была обращена ко многим проблемам, связанным с производительностью, однако управление состоянием до сих пор приходится осуществлять с помощью cookies, скрытых переменных данных или расширенных адресов. Обзор HTTP дается в главе 17, в то время как в приложении 7 приводятся подробности, касающиеся его форматов запроса и ответа.
MIME
MIME (Multipurpose Internet Mail Extensions, многоцелевые расширения электронной почты в Internet), невоспетый герой Web-протоколов, используется браузерами для определения типа данных, получаемых ими с сервера. В частности, HTTP-заголовок под названием content-type содержит значение MIME, которое браузер отыскивает для того, чтобы понять, данные какого типа он получает и что с ними делать. Серверы присоединяют MIME-типы к HTTP-заголовкам, генерируя их из программы или привязывая расширение файла (к примеру, html) к соответствующему MIME-типу (к примеру, text/html). MIME позволяет Web-сайтам представлять данные любого типа, а не только распространенные в Web форматы вроде HTML.
Адресация: URL/URI/URN/URC
Для запроса Web-страницы и связывания с ней необходимо использовать схему адресации. Пользователи Internet знакомы с унифицированным указателем ресурса (Uniform Resource Locator, URL), таким как http:// www.webdesignref.com/, определяющим протокол и местонахождение. В спецификациях более широко принятым термином, обозначающим короткие имена или строку адреса, ссылающуюся на ресурс в Internet, является унифицированный идентификатор ресурса (Uniform Resource Identifier, URI). Тем не менее, каково бы ни было название, URI и URL не предоставляют всей информации, которая может потребоваться в Internet в будущем, т. к. они указывают лишь на местонахождение.
ЛЕКЦИЯ 9.
PHP: ОСНОВЫ
Язык Web-программирования PHP
Что такое PHP
Синтаксис PHP довольно простой. Программы на РНР встраиваются в текст web-страницы так же, как и сценарии на JavaScript, VBScript, при помощи окаймляющих угловых скобок с вопросительными знаками и указанием языка:
<?php
...
текст программы
...
?>
Команды РНР обязательно разделяются символом точки с запятой - ";" (символ конца абзаца или конца строки не учитывается никак), после последней в программе команды его можно не ставить. Также символ ";'' не ставится после условных операторов (if, switch) и операторов цикла (for, while и других).
Пример программы на РНР - на рис. 3.1.
Рис. З.1. Программа на РНР (выделена жирным) в тексте web-страницы
Как и во всех языках программирования, в РНР есть возможность работать с переменными - некими объектами, имеющими имя и могущими принимать различные значения. Однако работа с переменными в РНР, пожалуй, самая легкая из всех возможных. Переменные не надо заранее объявлять (если не знаете, что это такое - то пока и не надо), разве что за исключением использования их в функциях. Для введения новой переменной достаточно просто присвоить ей какое-либо значение, а для помещения значения переменной в строку текста, имени файла или параметра команды, нужно просто написать ее имя в том месте, где должно быть ее значение. Чтобы РНР мог отличать переменные от строк или команд, имя переменной должно начинаться со знака доллара - ("$") и не должно содержать пробелов, знаков апострофа и некоторых других символов. При анализе программного кода интерпретатор РНР считает именем переменной все, что содержится между $ и ближайшим к нему символом, недопустимым в имени переменной.
В качестве имен переменных можно также использовать другие переменные - для этого другую переменную следует просто указать на месте имени первой: $$а.
Переменные в РНР
Переменные в РНР могут быть четырех типов - число (целое и дробное), строка текста, массив и объект1. Интерпретатор РНР автоматически определяет тип переменной на основании анализа ее содержимого. Подробнее о типах данных вы можете узнать в руководстве по РНР (например, в том, что доступно с сайта "РНР по-русски"), там же рассказано и об особенностях работы с массивами (и вообще объяснено, что это такое, если вы еще не знаете).
Для включения числовой или строковой переменной в строку текста достаточно просто поместить переменную туда, где она должна стоять в этой строке. Например, в итоге выполнения кода $а="птица певчая"; $b="Дятел - $а"; переменной $b будет присвоено значение "Дятел - птица певчая".
Помните, что в РНР нельзя для сложения строковых переменных использовать символ "+" - он пригоден лишь для числовых выражений. Поэтому необходимо помещать переменные в строки или использовать команду конкатенации (точку): $с = $а. $b.
Есть еще два типа переменных - PDF-документ и PDF-инфо, но они применяются только при работе с файлами PDF (и при установленном модуле поддержки PDF).
Довольно часто используются сокращенные обозначения арифметических действий над переменными и действий по присваиванию им каких-либо значений. Например, команда $а+=3 означает, что переменную $а надо увеличить на 3, что и будет сделано, если она имеет числовой формат. Точно так же команда $а- = 3 уменьшает переменную $ а на 3, а команды $а*=2 и $а/=2 соответственно умножают и делят на два переменную $а. Команда $а.=" строка" эквивалентна команде $а="$а строка".
В РНР применяются также операции инкремента и декремента, т.е. изменения значения переменной на 1. Так, команды $а++ и $а-- соответственно увеличивают и уменьшают значение переменной $а на единицу. То же самое делают и команды ++$а, --$а, однако, в том случае, если подобная команда используется в выражении, они, в отличие от предыдущих, сначала изменяют значение переменной, а потом выдают его в выражение. Иными словами, если переменная $а равна 2, то после выполнения команды $b=$а++; ее значение достигнет 3, а $b будет установлена в 2. В то же время команда $b= + + $а; установит обе переменные в 3.
9.3 Массив - это совокупность под одним именем перенумерованных переменных. Имя каждой переменной в массиве состоит из имени этого массива и индекса переменной - нечто вроде номера переменной в массиве или ее имени в нем. Индекс переменной может быть цифровым или символьным - т. е. представлять собой либо номер переменной в массиве, либо ее имя в нем.
Например, вот массив с числовыми индексами (нумерация индексов начинается с нуля, а не единицы!):
$а[0]=100; $а[1]=101; $а[2]=102;
а вот с символьными:
$а['first']=100; $а['second']=101; $а['third']=102;
(Массив с числовыми индексами называется еще "скалярным", а с символьными - "ассоциативным".)
Зачем нужны массивы? А для того чтобы можно было к ним обращаться как к чему-то целому, тем самым получая возможность возможность совершать автоматические действия со всеми элементами массива или с частью этих элементов, не указывая имени каждого их элемента.
Иными словами - скажем, в какие-то переменные записали имена клиентов и теперь желаем вывести их. Как это сделать? Естественно, только перебрав все эти переменные, для чего нам понадобятся имена этих переменных, которые придется жестко задать в программе. А если заранее неизвестно, сколько будет клиентов, как тогда быть? Если же имена клиентов поместить в массив, то все их можно перебрать специальной командой, добавить же новое имя тоже нетрудно.
В РНР добавлять элементы в массив можно как явно указывая индекс элемента (например, $а [100] = "Андрей";), так и просто упоминая, в какой массив этот элемент добавляется - $а [ ] ="Андрей";. В последнем случае добавляемый элемент становится последним в массиве.
Ниже перечислены некоторые основные команды РНР, которых вполне хватит для реализации несложных проектов. Для более полного ознакомления с командами РНР можно изучить Руководство по этому языку, доступное, например, с адреса http://php.spb.ru, или другие публикации.
include "имя файла" - команда для включения содержимого одного файла в другой. Содержимое файла, имя которого указывается в команде, целиком и полностью вставляется на то место, где располагается эта команда, при этом все коды РНР, содержащиеся во вставляемом файле, исполняются так же, как если бы они были на месте этой команды. (Помните, что файл именно вставляется - т. е., например, пути к картинкам, которые должны присутствовать во вставляемом файле, следует указывать от местонахождения того файла, в котором находилась команда include.)
Если файл, включаемый в страницу при помощи команды include, отсутствует, то вместо него размещается уведомление об этом, а программа на РНР выполняется дальше. (При необходимости завершения обработки и выдачи web-страницы в случае отсутствия включаемого файла, вместо команды include следует использовать команду require.)
mail ("Кому", "Тема", "Текст сообщения", "Дополнительные заголовки") - отправка почтового сообщения. При выполнении данной команды на сервере в соответствии с указанными параметрами формируется электронное письмо и отправляется с помощью установленной на сервере почтовой программы. В качестве параметра "Кому" может выступать набор адресов, разделенных запятыми. "Дополнительные заголовки" могут быть любые (естественно, допустимые почтовыми протоколами!), разделяться они должны должны комбинацией символов /п, которая в РНР означает перевод строки. (Если среди "Дополнительных заголовков" не указано поле From, то оно заполняется по умолчанию почтовой программой web-сервера, например, именем "Unprivileged User".)
echo ("текст") - вывод на web-страницу какого-либо текста. Чтобы вывести на web-страницу значение какой-либо переменной, достаточно просто написать ее имя внутри выводимой строки: команда echo "это цифра $а" выведет в web-страницу текст "это цифра 1", если ранее переменной $а было присвоено значение, равное единице. В случае необходимости использовать в выводимой строке кавычки или иные специальные символы перед этими символами следует ставить символ " \".
if (условие) {...команды, которые должны выполняться, если условие верно...;} else {...команды, которые должны выполняться, если условие неверно...} -команда, позволяющая выполнить то или иное действие в зависимости от истинности верности или ложности того или иного условия. В фигурных скобках может располагаться несколько команд, разделенных точкой с запятой. В качестве условия может быть оператор сравнения "равно" - ("==") (именно два-знака равенства!), "больше" -(">"), "меньше" - ("<") и их комбинации, скажем, "< = " - ("меньше или равно"). Можно использовать и несколько условий, взяв каждое из них, а также все вместе в скобки и разделяя знаками "&&" - ("и") или "| |" -("или").
Для того чтобы выполнять различные команды в зависимости от условия, которое может принимать три или больше значений, следует использовать оператор switch (описание смотрите ниже) - аналог оператора case в VBA и некоторых других языках.
for (начальное значение счетчика, условие продолжения цикла, изменение счетчика на каждом цикле) {... команды...;} - цикл, т. е. повторение указанных в нем команд столько раз, сколько позволит условие изменения счетчика цикла (т. с. переменной, специально выделенной для подсчета числа выполнений команд цикла). К примеру цикл for ($i = 1; $i <= 10; $i + +) {echo $i;} выводит в web-страницу числа с 1 до 10, так как в нем изначально устанавливается значение счетчика в 1 - ($i = l), каждый цикл его значение увеличивается на 1 - ($i ++), а продолжаться он будет до тех пор, пока значение счетчика не превысит 10 (т. е. пока $i< = 10).
while (условие) {...команды... } - цикл с условием. Команды в фигурных скобках выполняются до тех пор, пока выполняется условие в заголовке цикла. Для того чтобы цикл прервался, нужно, чтобы условие выполняться перестало - поэтому внутри цикла необходимо предусмотреть возможность влиять на это условие. Скажем, цикл while ($i<=10) {...команды...; $i++; } будет выполняться до тех пор, пока значение переменной $i не превысит 10 -если изначально оно было равно 1, то цикл выполнится 10 раз.
Цикл do {...команды... } while (условие) работает так же, однако команды, указанные в фигурных скобках, будут выполнены по меньшей мере один раз - даже если условие выполняться не будет.
Прервать выполнение любого цикла можно оператором break -дальнейшее выполнение программы пойдет с команды, следующей после закрывающей фигурной скобки. Оператор же continue прерывает текущую стадию выполнения цикла, т. е. после этого оператора дальнейшее выполнение программы начнется с очередной проверки условия заголовка цикла.
switch (выражение) {case значение:... команды...; break; case другое значение:... команды...; break;}
- оператор выбора. При его работе содержимое, заключённое в фигурные скобки, просматривается сверху вниз. Как только будет найден оператор case со значением, совпадающим со значением выражения, РНР начнёт выполнять весь код, следующий за этим оператором case до последней фигурной скобки оператора switch или до первого оператора break, в зависимости от того, что появится раньше. (Обратите внимание, что если команду break не указать в конце кода, относящегося к одному варианту значения выражения в заголовке оператора switch, PHP будет выполнять код дальше - т. е. тот, который принадлежит уже следующему оператору case! Это - одно из отличий данного оператора от аналогичных в других языках программирования.)
В конце оператора switch можно указать оператор default. Код, стоящий после него, выполнится в том случае, если значение выражения в заголовке оператора не совпадет ни с одним из значений после операторов case.
foreach (переменная as массив) {...команды...;} - поочередное считывание всех элементов массива. Foreach считывает в указанную в его параметрах переменную поочередно все элементы указанного в них же массива, выполняя каждый раз указанный в фигурных скобках код, в котором может использоваться указанная переменная. (Значения элементов массива этим оператором только считываются, их модификация при помощи команды f oreach невозможна.) Оператор f oreach может быть использован только в РНР версии 4.0 и выше.
Программа на РНР может прерываться кодом web-страницы - для этого достаточно вставить закрывающий тэг до этого кода и открывающий - после. Все, что находится между ними, будет выдаваться в браузер без какой-либо обработки, рассматриваясь как выводимое с помощью команды echo. Иными словами, код
<?php if ($a==l) {?><р>Переменная а равна 1</p><?php> }?>
эквивалентен коду
<?php if ($a==l) {echo "<p> Переменная а равна
1</p>";}?>
однако, первый вариант меньше нагружает процессор компьютера, на котором расположен интерпретатор РНР.
Из сказанного также следует, что все программы на РНР, расположенные на одной web-странице, представляют собой одну большую программу, несмотря на то, что они разделяются блоками обычного текста страницы. Именно поэтому переменная, объявленная в расположенном в начале страницы коде, сохраняет свое значение не только до ее конца, но и во всех присоединяемых с помощью команды include файлах. Пример - на рис. 3.2.
В РНР можно создавать функции - подпрограммы, которые можно вызывать по своим именам, при необходимости передавая им определенную информацию. Необходимы они в том случае, когда один и тот же код нужно выполнять несколько раз для разных данных, особенно если требуемое количество выполнений заранее неизвестно. Создать функцию на РНР можно, вставив в программу инструкцию function имя (переменные, в которые записываются передаваемые параметры, и их тип) {...команды функции... }, а вызвать - простым указанием имени этой функции и параметров.
Рис. 3.2. Пример PHP-кода. Посмотрите внимательно на код и результат его
отображения. Обратите внимание, что переменная а, которой присвоено
значение еще в первом программном блоке левой страницы, сохранила его
не только в других ее блоках, но и в программе, расположенной во
включаемой с помощью команды include странице
Помните, что переменные, созданные в функции, по умолчанию имеют установленное значение только внутри функции. Кроме того, также по умолчанию переменные, объявленные вне функции, в ней самой никакого значения не имеют, а если надо, чтобы имели, то вначале функции их следует "подключить" командой global <пе-ременная>; - и лишь после этого они станут доступными в функции. Подробнее о функциях и о переменных в них читайте в руководстве по РНР, например, с того же сайта http://php.spb.ru.
Обычно web-сервер настраивается так, что на предмет наличия программ на РНР просматриваются файлы, имеющие расширение.php,.php3,.phtml, остальные же файлы передаются в браузер пользователя без поиска в них команд РНР. Делается так для более быстрой работы сервера, а также для обеспечения возможности установки на сервере разных интерпретаторов (например, SSI - Server Side Includes, технологии, в какой-то мере предшествовавшей РНР), так как тогда каждому из интерпретаторов назначаются свои расширения для обработки соответствующих файлов.
Так как РНР-код полностью исполняется на web-сервере, то в страницах, выдаваемых браузеру, он будет отсутствовать, и если кто заинтересуется вашим опытом программирования, то вам придется отправлять ему этот код по почте, так как при просмотре сайта каким-нибудь образом узнать исходный PHP-код его страниц нельзя.
РАБОТА С ФОРМАМИ
Значения переменных можно передавать между различными страницами сайта - с помощью использования форм. Формой называется конструкция, состоящая из поименованных элементов особых типов, заключенных между HTML-тэгами <form...> n</form>. В качестве элементов формы могут выступать поля ввода текста, кнопки, выпадающие меню, переключатели, квадратики для отметки галочкой -checkbox'bi, а также картинки формата jpg или gif. Каждый элемент формы может иметь свое имя.
Наиболее важным свойством формы является то, что в ее заголовке в открывающем тэге <form...> можно указать адрес какого-либо файла. В этом случае при загрузке этого файла в программный код, если он будет там присутствовать, передадутся значения всех переменных, установленных в этой форме, в частности, значения всех элементов формы, как если бы эти значения были установлены в программе, расположенной в самом загружаемом файле. Таким образом можно передавать значения переменных между различными web-страницами, используя их в программном коде.
Во всех версиях РНР имена передаваемых переменных соответствуют тем именам, которые были даны элементам формы в их тэгах, а значения - соответственно значениям этих элементов (если в конфигурационном файле РНР - php.ini - параметр regis-ter_globals установлен в on.): для поля ввода текста - введенному тексту, для переключателя или checkbox'a - True при отмеченном и False при неотмеченном, для рисунка - координаты указателя мыши относительно верхнего левого угла изображения, для выпадающего меню (элемент <select пате="имя"><орtion value="textl">text</option>...</select>) - значение параметра value выбранного пункта option.
Кроме того, переменные, передаваемые через форму, помещаются в ассоциативные массивы $HTTP_POST_VARS и $HTTP_GET_VARS (если в конфигурагцюнном файле РНР - php.ini - параметр track_vars установлен в on) с именами элементов, соответствующими именам переменных (т. е. содержимое поля ввода текста <input type=text name=qwerty size=3 0> окажется в элементе $HTTP_POST_VARS['qwerty']). SHTTPPOSTVARS содержит переменные, переданные с помощью метода POST (метод указывается в заголовке формы), а $HTTP_GET_VARS - метода GET. Различие между методами состоит в том, что при передаче данных методом GET эти данные отображаются в адресной строке браузера, а при использовании метода POST - нет.
Начиная с РНР версии 4.1, передаваемые через форму переменные помещаются еще и в массивы SPOST и SGET. Отличие этих массивов от предыдущих состоит в том, что их переменные доступны еще и во всех функциях, расположенных в программе РНР, т. е. они являются глобальными.
РНР: ВЫБОРОЧНАЯ ЗАГРУЗКА
В этой главе приведен пример простого PHP-сценария, используемого на реально существующем сайте.
Сайт www.harchikov.ru посвящен творчеству певца-барда Александра Харчикова. На сайте должны были быть представлены вышедшие альбомы певца в количестве 15 шт. и записи песен каждого альбома в МРЗ-формате. При создании сайта возникла необходимость обеспечить удобную навигацию. Общепринятый способ - ссылки на страницы с описанием каждого из альбомов и песнями из него - имел тот недостаток, что посетитель, желающий просмотреть не один альбом, а сразу несколько, был бы вынужден постоянно переходить со страницы на страницу, делая лишние усилия. Кроме того, в случае разрыва связи во время загрузки какого-либо файла посетитель, ушедший на другую страницу, был бы вынужден снова возвращаться на ту, с которой он этот файл загружать начал, тратя время на ее поиск. Недостаток другого варианта - размещения информации о всех альбомах на одной странице - ясен: размер этой страницы получ'ился бы очень большим, а интересная посетителю информация могла бы занимать лишь небольшую ее часть.
Поэтому было сделано так. На главной странице разместилась форма, а у каждого названия альбома - checkbox, внизу же страницы -кнопка перехода на список альбомов. Посетитель мог отметить заинтересовавшие его альбомы (рис.4.1), и после нажатия кнопки перехода PHP-сценарий выводил ему страницу с описаниями лишь тех альбомов, которые посетитель выбрал (рис.4.2).
Чтобы добиться такого результата, всем checkbox'aM заглавной страницы сайта были присвоены имена: <INPUT name=pan01 type=checkbox>. Все эти checkbox'bi находятся в большой форме, параметром action которой является имя файла с программой на РНР, выводящей описания альбомов в соответствии с данными этой формы, а для передачи данных формы используется метод get (т. е. ее заголовок имеет вид <FORM action=albm.php method=get name=forma>). Последнее приводит к тому, что в адресе страницы с выведенными описаниями альбомов присутствуют переменные (см. рис. 4.2), т. е. если посетитель занесет этот адрес в "Избранное", то при последующих возвращениях на сайт по этой ссылке (например, для дальнейшей загрузки песен выбранных альбомов) ему не придется вновь выбирать альбомы на заглавной странице, как это было бы в случае использования метода post, не помещающего имена переменных и их значения в строку адреса (что, впрочем, выглядит красивее).
Рис. 4.1. Чтобы просмотреть лишь избранные альбомы, достаточно их отметить...
Кнопка, вызывающая переход на страницу, указанную в параметре action заголовка формы, должна иметь тип submit, например:
<input type=submit value="Вывести оглавления отмеченных альбомов">.
Рис. 4.2....и вот, как на ладони -только они
Загрузив заглавную страницу сайта www.harchikov.ru, можно легко изучить структуру расположенной на ней формы, что вы и сделайте, если описание вам непонятно.
В файле же albm.php (адрес именно этого файла указан в заголовке формы заглавной страницы) помещена простая программа, которая выглядит так:
<?php
if ($bar01==True) {include ("bar01.php"); }
if ($bar02==True) {include ('bar02.php"); }
... по строке на каждый альбом...
?>
В файлах bar01.php, bar02.php и т. д. находятся описания альбомов и ссылки на МРЗ-файлы песен. Если checkbox с соответствующим именем был отмечен на заглавной странице, то переменная его имени оказывается равной True - именно это и проверяется в сценарии.
Удивительно, что этот простейший прием в настоящее время практически не применяется на сайтах Сети - используется традиционная схема размещения информации со множеством ссылок на отдельные разделы. А ведь как удобно - например, на сайте Харчикова можно выбрать альбомы, сгенерировать себе страницу со ссылками на песни из них и, заходя на нее, постепенно загружать песни или передать весь список ссылок на файлы в какую-нибудь из программ-"качалок". Или, скажем, на сайте фирмы "Экон-Профи" (http://www.econprofi.ru) точно так же сделан раздел "Вопросы и ответы" (рис.4.3) - отметив интересующие вопросы на странице раздела, можно получить подробные консультации исключительно по выбранным темам. Полученная страница и загрузится быстрее, да и при ее распечатке лишней бумаги тратить не потребуется.
Рис. 4.3. Если вас заинтересовали лишь отдельные вопросы, нет надобности загружать всю страницу
Данную схему, разумеется, можно доработать. Опыт показывает, что посетители чаще всего предпочитают просмотреть либо два-три выбранных раздела, либо все разделы сразу. В последнем случае им придется отмечать все checkbox'bi страницы, что занимает время и силы. Поэтому стоит поместить на страницу еще и кнопку вывода сразу всех разделов - "Просмотреть все". Ей можно назначить гиперссылку с адресной строкой, содержащей все переменные в значении on, а можно немного доработать код РНР на странице-обработчике запроса, попросту добавив во все условия проверку значения еще одной, общей для всех условий переменной: if (($bar02==True) || ($all==True)) {... (напоминаю, что знак || означает "или"), и тогда гиперссылка может вести всего лишь на адрес albm.php?all=True.
Можно для решения той же задачи поместить на страницу пару сценариев на JavaScript, выполняющих соответственно отметку всех checkbox'oв и, наоборот, их очистку. Так что простор для творчества имеется, и немалый.
РНР: ГОСТЕВАЯ КНИГА
Вы наверняка неоднократно встречали в Интернете такой сервис, как гостевые книги, т. е. web-страницы, на которых каждый посетитель может оставить свой отзыв, который будет «виден» другим посетителям, впоследствии зашедшим на страницу. Скорее всего, вы думали, что создание гостевой книги требует долгого и сложного программирования.
Не спорю, сделать крупный Интернет-портал, предоставляющий всем желающим гостевые книги для установки на сайт, довольно трудно. Однако на языке программирования РНР организация простой системы оставления сообщений может быть создана всего несколькими строками кода. Причем нетрудно заставить эти строки обслуживать сразу несколько отдельных гостевых книг, скажем, дать посетителям возможность оставлять свои комментарии и отзывы о различных материалах, размещенных на сайте, на тех же самых страницах, на которых эти материалы размещены. Или, допустим, организовать разные книги для разных категорий посетителей.
Данная глава, как вы, наверное, уже поняли, посвящена рассказу о сценарии на РНР для создания простейшей гостевой книги. В главе разобран сценарий, позволяющий сделать на одном сайте несколько гостевых книг. Очевидно, что приспособить его для работы всего одной гостевой книги элементарно.
Схема работы сценария простой гостевой книги такова.
Для хранения сообщений выделена специальная папка, в которой каждое сообщение хранится в отдельном текстовом файле. Для того чтобы можно было различать сообщения, принадлежащие разным гостевым книгам, каждая книга имеет свой индекс (например, "gbOl"), который указывается в специальном сценарии в ее тексте. Имя каждого файла с сообщением начинается с этого индекса (см. рис. 9.1).
Поскольку в гостевой книге, как нетрудно догадаться, количество сообщений весьма скоро превысит одно, то файлы с ними нужно еще и последовательно нумеровать. Вернее, не "последовательно", а так, чтобы их можно было отсортировать - наверное, достаточно возможности сортировки лишь по дате появления.
В РНР есть интересная функция - time (); она выдает количество секунд между 1 января 1970 года (этот момент считается началом "эпохи Unix") и текущим временем, так называемую "временную метку Unix". (В настоящее время эта величина - чуть больше миллиарда.) Посмотрите - если имя файла с сообщением составлять из индекса гостевой книги и временной метки Unix (см. рис. 9.1), то, во-первых, каждое сообщение будет обладать своим уникальным именем (посылка нескольких сообщений в гостевую книгу разными пользователями в одну и ту же секунду теоретически возможна, но маловероятна), а, во-вторых, их легко можно будет отсортировать по времени появления (время ведь вспять не течет - каждое новое сообщение будет получать большую метку, нежели любое предыдущее).
Бесспорно, так как сортировка имен, состоящих из индекса и временной метки, будет проводиться по законам сортировки строк (т. е., скажем, 21 будет стоять раньше 3 при сортировке по возрастанию - т. к. сравнение ведется с начала строки), то при увеличении разрядности временной метки новые сообщения окажутся посреди старых. Однако какие-либо проблемы в нашем случае начнутся не раньше момента достижения временной меткой значения в 10 миллиардов, а до него еще больше, чем две с половиной сотни лет...
Рис. 9.1. Гостевая книга - все ее файлы
Итак, вот алгоритм работы сценария гостевой книги:
1. 1. При загрузке посетителем страницы книги просканировать папку с сообщениями, выбрать оттуда сообщения, относящиеся к данной книге (попросту найдя в именах содержащих их файлов индекс этой книги), отсортировать их и вставить в web-страницу.
2. 2. При вводе посетителем сообщения пересчитать уже имеющиеся и сохранить новое сообщение в файле с именем, состоящим из индекса текущей гостевой книги и временной метки Unix.
Есть, впрочем, еще одно пожелание. Обратите внимание - если следовать данному алгоритму, то сообщение, помещенное посетителем в гостевую книгу, будет просто вставлено в текст той страницы, на которой она расположена. А это значит, что какой-нибудь злоумышленник вполне может поместить в сообщение гостевой книги код на РНР и тот будет преспокойно выполнен! А результат такого выполнения для владельца сайта непредсказуем. Это может быть и удаление с сайта всех файлов, и размещение на нем совсем не того, что хотелось бы, и массовая почтовая рассылка....Поэтому наш алгоритм следует дополнить еще одним пунктом:
1. 3. Перед сохранением сообщения посетителя в файл удалить из него все тэги или сделать их нераспознаваемыми ни интерпретатором РНР, ни браузером - например, конвертировав в соответствующие им сочетания символов, попросту отображающие их на экране.
Ну а теперь посмотрим, как все это реализуется на РНР.
В текст каждой web-страницы, на которой должна быть расположена гостевая книга, следует вставить следующий код (см. рис. 9.2):
<?php
$пот="уникальная аббревиатура книги, без пробелов и специальных символов, например, book01";
include ("niz.php");?>
Думается, смысл этого сценария ясен - вначале устанавливается индекс гостевой книги, а затем включается единый для всех книг файл с собственно отображающим сообщения кодом - в данном случае niz.php.
Поскольку именно код файла niz.php отображает сообщения гостевой книги, то и вышеприведенный фрагмент кода следует помещать именно там, где эти сообщения должны на web-странице располагаться.
Рис. 9.2. Всего три файла - и гостевая книга. А можно даже два
Содержимое же файла niz.php (см. рис. 9.2) может быть таким (пояснения относятся к коду под ними):
<?php
Укажем имя папки, в которой будут сохраняться отзывы (ее, разумеется, вначале надо будет создать на аккаунте сайта вручную). Само имя может быть любым - важно лишь, чтобы оно не содержало пробелов или специальных символов:
$dirct="gb";
Ну а далее следует уже знакомый вам сценарий "Папкопотрошилки" (см. гл. 6), применяемый к этой самой папке с отзывами. Вот практически точно такой же, как и в "Папкопотрошилке", код, записывающий в массив $а[] имена всех файлов, в имени которых содержится указанный выше индекс книги:
$hdl=opendir($dirct);
while ($file = readdir($hdl))
if (strstr($file, $nom)!=False)
$a[]=$file;
closedir($hdl);
Примечание:
Функция strstr ищет в своем первом аргументе строку, указанную вторым аргументом, и возвращает True, если ее там находит.
Теперь отсортируем полученный массив. Для этого сначала узнаем количество сообщений книги:
$l=sizeof($a);
а затем, в том случае, если сообщения в книге есть, произведем сортировку (если сообщений нет, т. е. массив $а пуст, то функция сортировки выдаст ошибку, а дальнейшая работа с элементами массива вообще бессмысленна - поэтому нужна проверка размера массива):
if ($l!=0)
{
rsort($a);
Теперь массив $а содержит имена файлов с сообщениями, причем в первых элементах массива содержатся имена файлов с наибольшими номерами (т. е. самые новые - как и следует из приведенного выше алгоритма). Если же требуется обратный порядок (т. е. чтобы новые сообщения помещались в конец страницы), то вместо функции rsort (сортировка по убыванию) следует использовать функцию sort (т. е. сортировка по возрастанию).
Ну и, наконец, вставим все файлы с сообщениями в страницу с гостевой книгой с помощью оператора include, перебрав последовательно элементы массива с именами этих файлов конструкцией foreach:
foreach ($a as $value)
{
include ("$dirct/$value");
echo ("<br>(разделитель сообщений)");
Как уже говорилось, foreach считывает в указанную в его параметрах переменную - в данном случае $value - все элементы массива - в данном случае $а - по очереди, выполняя каждый раз указанный после него в фигурных скобках код, в котором указанная переменная может использоваться. Поскольку в массиве первыми идут элементы с именами файлов с наиболее новыми сообщениями, то и на странице эти сообщения появятся сверху.
Комментарий:
Оператор foreach будет работать только в РНР 4.0 и выше. Если вы можете использовать лишь РНРЗ, то вместо него можно использовать цикл for, указав в его параметрах величину массива $1:
for ($k = 1; $k < $1; $k++) {
Для удобства можно записать значение очередного элемента массива в переменную: $value=$a[$k];
Все - код вывода имеющихся с
Воспользуйтесь поиском по сайту: