|
Этапы создания веб-приложения. Основы РНР и MySQL
Этапы создания веб-приложения. Основы РНР и MySQL
Этапы создания веб-приложения. Основы РНР и MySQL - Лекция
- План
- ВВЕДЕНИЕ
- 1. Что такое веб-программирование. Основные технологии
- 1.1. Клиент-Сервер
- 1.2. HTML-формы. Методы отправки данных на сервер с помощью формы
- 1.3. Технология CGI
- 2. PHP: Препроцессор Гипертекста
- 2.1. Что такое PHP?
- 2.2. Возможности PHP
- 2.3. Почему нужно выбирать PHP
- 2.4. Недостатки PHP
- 2.5. Встраивание PHP в HTML - форму
- 2.6. HTML-формы. Массивы $_GET и $_POST
- 2.6.1. Особенности метода отправки формы POST
- 2.6.2. Особенности метода отправки формы GET
- 2.7. Функция htmlspecialchars()
- 2.8. Применение функции phpinfo() для отладки
- 3. Что такое MySQL
- 3.1. Возможности MySQL.
- 3.2. Примеры использования PHP совместно с MySQL
- 3.2.1. Работа с формами
- 3.2.2. Сохранение данных в базе данных MySQL
- 3.2.3. Получение (извлечение) данных из базы данных MySQL
- ВВЕДЕНИЕ
- Основные технологии веб-программирования. Методы отправки данных на сервер с помощью HTML-формы. PHP - Препроцессор Гипертекста. Сохранение данных в базе данных MySQL. Клиент-Сервер и технология CGI. Примеры использования PHP совместно с MySQL.
- Рассмотрим основные этапы создания web-приложения на языке PHP.
- Предполагается, что Вы знаете основы языка разметки HTML и имеете небольшой опыт программирования.
- Прежде, чем приступать к созданию web-приложения, нужно выяснить, что понимают под web - программированием.
1. Что такое веб-программирование. Основные технологии1.1. Клиент-СерверКогда Вы программировали, например, на Delphi, Visual Basic, или Visual C++, то привыкли к такой схеме работы программы: нажимаете кнопку на клавиатуре > выполняется код > выводится результат. Все это выполняется на одном компьютере.В web -программировании все обстоит по-другому.Когда Вы вводите в адресной строке браузера URL (Universal Resource Location, или в просторечии - адрес) происходит следующее:? Браузер открывает соединение с сервером.? Браузер отправляет серверу запрос на получение страницы.? Сервер формирует ответ (чаще всего - HTML-код) браузеру и закрывает соединение.? Браузер обрабатывает HTML-код и отображает web -страницу, которую Вы видите на экране монитора.Еще до того, как Вы увидели на экране запрошенную страницу, соединение с сервером закрыто, и он о Вас забыл. И когда Вы введете другой (или тот же самый) адрес, или щелкните по ссылке, или нажмете на кнопку HTML-формы - та же схема повторится снова.Такую схему работы называют "клиент-сервер". Клиент в данном случае - браузер.Соединение с web -сервером длится промежуток времени между щелчком по ссылке (или другим способом запроса) и началом отображения web -страницы. Большинство браузеров во время соединения отображают индикатор, например, индикатор MS Internet Explorer отображает анимацию в правом верхнем углу.Внимательный студент может заметить - а как же так, я уже читаю страницу, а индикатор все еще показывает процесс соединения? Дело в том, что тэг <img src=...> (загрузка изображения) и некоторые другие теги HTML - кода - это еще один запрос к серверу. Выполняется он точно так же, как и любой другой запрос - по той же схеме.Чтобы навсегда избавиться от восприятия HTTP как "черного ящика", "притворимся" браузером с помощью telnet'а:1. Запустим telnet www.php5.ru 802. Введем в окне терминала следующее (если ввод не отображается - ничего страшного):GET / HTTP/1.0 [здесь нажмем Enter]Host: www.php5.ru [здесь нажмем Enter дважды]Нажатие Enter соответствует, как правило, комбинации символов CR + LF, обозначаемых как \r\n. Далее будет использоваться именно это обозначение.По экрану монитора пробежит HTML-код страницы http://www.php5.ru/.HTML-код текущей страницы можно просмотреть практически в любом браузере, выбрав в меню "Вид|Просмотр HTML-кода":Картинки, фреймы - это дополнительные запросы: при обработке (парсинге) HTML-кода, браузер, натыкаясь на тэг <img src="картинка"> осуществляет дополнительный запрос к серверу - запрос картинки, и отображает ее на месте, где стоит тэг <img...>.Введите:telnet www.php5.ru 80GET /php/php5ru.png HTTP/1.0\r\nHost: www.php5.ru\r\n\r\n По экрану пробежит то, что бы вы увидели, если б просмотрели этот png-файл в текстовом редакторе.1.2. HTML-формы. Методы отправки данных на сервер с помощью формыОдно из наиболее распространенных приложений любого языка создания серверных сценариев - обработка HTML - форм. Web-программирование в большей части представляет собой обработку различных данных, введенных пользователем. РНР облегчает задачу обработки и разбора форм, поступивших из браузера, так как в язык на самом нижнем уровне встроены все необходимые возможности. Поэтому программисту не приходится даже и задумываться над особенностями протокола HTTP и размышлять, как же происходит отправка и прием роsт-форм или даже загрузка файлов. С HTML-формами Вы уже встречались при изучении языка разметки HTML. Рассмотрим пример посылки сообщения из формы по электронной почте. Листинг e_mail.html. Посылка сообщения из формы по e-mail <html> <head> <title>Посылка формы по е-mail</title> </head> <body> <FORM action=mailto: myaddres@mail.ru enctype=”text/plain” method=”post”> Нажмите “Cброс” и заполните заказ.<BR> <INPUT type=reset value=C6poc><BR> <P> <TABLE border=0 cellspacing=O cellpadding=5> <TR> <TD>Ваше имя:</TD > <TD> <INPUT type=text size=33 name=name value=”Прохоров Виктор Сергеевич”> </TD> </TR> <TR> <TD>Ваш адрес:</TD> <TD> <INPUT type=text size=33 name=email value=prohwik@mail.ru > </TD> </TR> <TR> <TD>Прислать:</TD> <TD> <INPUT type=text size=33 name=obj value=”Методические указания”> </TD> </TR> </TABLE> <INPUT type=submit value=”Послать заказ”> </FORM> </body> </html> Если обработать этот HTML-код браузером, то отобразится web -страница, которую можно увидеть на экране монитора: Пользователь нажимает кнопку «Сброс», и поля принимают значения, установленные по умолчанию. Форма заполняется пользователем, и по нажатию кнопки «Послать заказ» отправляется по адресу myaddres@mail.ru. Обычно браузер не сам отсылает форму, а поручает эту работу почтовой программе, установленной по умолчанию в операционной системе компьютера (например, Outlook). Письмо посылается в виде: subjct: Форма отправлена из Microsoft Internet Explorer name = Прохоров Виктор Сергеевич value=prohwik@mail.ru obj = «Методические указания» Письмо составляется из пар имя=значение, которые выбираются по порядку из полей формы. Рассмотрим подробнее следующий пример. Листинг form_1.html <form method="GET" action="/cgi-bin/form_handler.cgi"> Введите Ваше имя: <input type="text" name="name"> <br> <input type="submit" name="okbutton" value="OK"> </form> Сохранив этот код в HTML-файле form_1.html и просмотрев его с помощью браузера, можно увидеть HTML-форму: Форма реализована тегом-контейнером <form>. Тег своими атрибутами указывает: ? адрес сценария, которому будет послана форма; ? способ пересылки и характеристику данных, содержащихся в форме. Начальный <form> и конечный </form> теги задают границы формы. Их указание является обязательным. Атрибуты тега-контейнера <form> (все необязательные): ? action --атрибут, в качестве значения которого указывают URL-адрес (полный или относительный) запрашиваемой CGI-программы. Эта программа будет обрабатывать данные, содержащиеся в форме. Допустимо использовать запись MAILTO:URL. В этом случае форма будет послана по электронной почте. Если атрибут action не указать, то содержимое формы будет отправлено на URL-адрес, с которого загружена данная web-страница, то есть "саму на себя". Это удобное сокращение, но по стандарту HTML атрибут action обязателен. ? method -- определяет метод HTTP, используемый для пересылки данных формы от браузера к серверу. Атрибут method может принимать два значения: get или post: ¦ get - отправка данных формы в адресной строке. Вы могли заметить на различных сайтах присутствие в конце URL символа "?" и следующих за ним данных в формате параметр=значение. Здесь "параметр" соответствует значению атрибута name элементов формы (см. ниже про тэг <input>), а "значение" - содержимому атрибута value (в нем, например, содержится ввод пользователя в текстовое поле того же тэга <input>). Для примера - попробуйте поискать что-нибудь в Яндексе и обратите внимание на адресную строку браузера. Это и есть способ get. ¦ post - данные формы отправляются в теле запроса. Если не совсем понятно (или совсем непонятно), что это такое - не беспокойтесь, скоро мы к этому вопросу вернемся. Если атрибут method не указан - подразумевается "get". ? enctype -- необязательный атрибут. Указывает тип содержимого формы, используемый для определения формата кодирования при ее пересылке. В HTML определены два возможных значения для атрибута enctype: ¦ APPLICATION/X-WWW-FORM-URLENCODED (используется по умолчанию). ¦ MULTIPART/FORM-DATA. Тег <input> позволяет создавать внутри формы поля ввода строки текста, имени файла, пароля и др. У <input> нет конечного тега. Атрибуты и особенности использования <input> зависят от способа его использования. Тэг <input> - задает элемент формы, определяемый атрибутом type: ¦ Значение "text" задает однострочное текстовое поле ввода. ¦ Значение "submit" задает кнопку, при нажатии которой происходит отправка формы на сервер. Возможны и другие значения (да и <input> - не единственный тэг, задающий элемент формы), но их мы рассмотрим в следующих главах. Итак, что же происходит, когда нажимают кнопку "OK"? 1. Браузер просматривает входящие в форму элементы и формирует из их атрибутов name и value данные формы. Допустим, введено имя Vasya. В этом случае данные формы: name=Vasya&okbutton=OK. 2. Браузер устанавливает соединение с сервером, отправляет на сервер запрос документа, указанного в атрибуте action тэга <form>, используя метод отправки данных, указанный в атрибуте method (в данном случае - GET), передавая в запросе данные формы. 3. Сервер анализирует полученный запрос, формирует ответ, отправляет его браузеру и закрывает соединение. 4. Браузер отображает полученный от сервера документ. Отправка того же запроса вручную (с помошью telnet) выглядит следующим образом (предположим, что доменное имя сайта - www.example.com): telnet www.example.com 80 GET /cgi-bin/form_handler.cgi?name=Vasya&okbutton=OK HTTP/1.0\r\n Host: www.example.com\r\n \r\n Нажатие submit-кнопки в форме с методом отправки "GET" аналогично вводу соответствующего URL (со знаком вопроса и данными формы в конце) в адресной строке браузера: http://www.example.com/cgi-bin/form_handler.cgi?name=Vasya&okbutton=OK На самом деле, метод GET используется всегда, когда Вы запрашиваете с сервера какой-либо документ, просто введя его URL, или щелкнув по ссылке. При использовании <form method="GET" ... >, к URL просто добавляются знак вопроса и данные формы. Как же нам в сценарии получить строку параметров, переданную после знака вопроса в URL при обращении к сценарию? Для этого можно проанализировать переменную окружения QUERY_STRING, которая в РНР доступна под именем $_SERVER[QUERY_STRING]. Напишем пример, чтобы это проиллюстрировать (листинг qs.php). Листинг qs.php. Вывод параметров командной строки. <?php echo «Данные из командной строки: $_SERVER[QUERY_STRING]»; ?> Если теперь запустить этот сценарий из браузера (перед этим сохранив его в корневом каталоге сервера) таким образом: http://localhost/qs.php?this+is+the+world/ то получим документ следующего содержания: Данные из командной строки: this+is+the+world Обратите внимание на то, что URL-декодирование символов не произошло: строка $_server [' query_string '], как и одноименная переменная окружения, всегда приходит в той же самой форме, в какой она была послана браузером. Так как РНР изначально создавался именно как язык для Web-программирования, то он дополнительно проводит некоторую работу с переменной query_string перед передачей управления сценарию. А именно, он разбивает ее по пробельным символам (в примере пробелов нет, их заменяют символы +, но эти символы РНР также понимает правильно) и помещает полученные кусочки в массив-список $argv, который впоследствии может быть проанализирован в программе. Массив $argv используется при программировании на РНР крайне редко, что связано с большими возможностями интерпретатора по разбору данных, поступивших от пользователя. Однако в некоторых (учебных) ситуациях его применение оправдано. Возможно, все эти технические подробности кажутся невероятно скучными и даже ненужными ("а при чем тут PHP?"). Но это основы работы по протоколу HTTP, которые необходимо знать каждому web-программисту. Теперь заменим первую строку нашей формы на следующую: <form method="POST" action="/cgi-bin/form_handler.cgi"> Мы указали метод отправки "POST". В этом случае данные отправляются на сервер несколько другим способом: telnet www.example.com 80 POST /cgi-bin/form_handler.cgi HTTP/1.0\r\n Host: www.example.com\r\n Content-Type: application/x-www-form-urlencoded\r\n Content-Length: 22\r\n \r\n name=Vasya&okbutton=OK При использовании метода POST данные формы отправляются уже после "двух Enter-ов" - в теле запроса. Все, что выше - на самом деле заголовок запроса (и когда мы использовали метод GET, данные формы отправлялись в заголовке). Для того, чтобы сервер знал, на каком байте закончить чтение тела запроса, в заголовке присутствует строка Content-Length; о том же, что данные формы будут переданы виде параметр1=значение1&параметр2=значение2..., причем значения передаются в виде urlencode - то есть, точно так же, как и с помощью метода GET, но в теле запроса, - серверу сообщает заголовок "Content-Type: application/x-www-form-urlencoded". О том, что такое urlencode - чуть ниже. Преимущество метода POST: отсутствие ограничения на длину строки с данными формы. При использовании метода POST невозможно отправить форму, просто "зайдя по ссылке", как было с GET. Для краткости изложения, введем термины "GET-форма" и "POST-форма", где префикс соответствует значению атрибута method тэга <form>. При использовании POST-формы, в ее атрибуте action можно указать после знака вопроса и параметры GET-формы. Таким образом, метод POST включает в себя и метод GET. 1.3. Технология CGIМы разобрались, как создать HTML-форму, и как браузер отправляет введенные в нее данные на сервер. Но пока не понятно, что будет сервер делать с этими данными.Сам по себе web-сервер умеет только отдавать запрошенную страницу, и ничего более того, и ему все переданные данные формы, в общем-то, совершенно безразличны. Для того, чтобы можно было обработать эти данные с помощью какой-либо программы и динамически сформировать ответ браузеру, и была изобретена технология CGI (Common Gateway Interface).Взглянем на этот URL: http://www.example.com/cgi-bin/form_handler.cgi. Первое предположение, которое можно сделать на его счет, обычно такое: сервер отдает содержимое файла form_handler.cgi из каталога cgi-bin. Однако, в случае с технологией CGI дело обстоит по-другому. Сервер запускает программу form_handler.cgi и передает ей данные формы. Программа же формирует текст, который передается браузеру в качестве ответа на запрос.Программу form_handler.cgi можно написать на любом языке программирования, главное - соблюдать в программе стандарт CGI. Можно использовать, например, популярный скриптовый язык Perl. А можно написать все на Си, или на shell-скриптах... Для примера, напишем эту программу на Си. Но сначала разберемся, как происходит обмен данными между web-сервером и CGI-программой:1. Перед запуском CGI-программы, сервер устанавливает переменные окружения (Вам они наверняка знакомы по команде PATH). В каждый мало-мальски серьезном языке программирования есть средства для чтения переменных окружения. Стандарт CGI определяет весьма значительный набор переменных, которые должны быть определены перед запуском CGI-программы. Рассмотрим сейчас только три из них:REQUEST_METHOD - метод передачи данных - GET или POST (есть и другие, но пока мы их не рассматриваем)QUERY_STRING - содержит часть URL после вопросительного знака, или, другими словами, данные GET-формы.CONTENT_LENGTH - длина тела запроса (данные POST-формы).2. Сервер запускает CGI-программу. Тело запроса передается программе в виде стандартного ввода (stdin) - будто бы эти данные были введены с клавиатуры.3. Программа выдает ответ браузера на стандартный вывод (stdout) - "на экран". Этот вывод перехватывается веб-сервером и передается браузеру.Это CGI-программа на Си, выводящая содержимое полученных от web-сервера параметров форм:1. #include <stdio.h>2. #include <stdlib.h>3.4. int main(void)5. {6. // Читаем переменные среды, установленные веб-сервером7. char *query_string = getenv("QUERY_STRING");8. char *request_method = getenv("REQUEST_METHOD");9.10. char *post_data; // Буфер для данных POST-запроса11. int post_length = 0; // Длина тела запроса12.13. if (strcmp(request_method, "POST") == 0) {// Если получен POST-запрос,14. post_length = atoi(getenv("CONTENT_LENGTH")); // сначала читаем из 15. // переменной среды его длину,16. if (post_length) {// если она не нулевая,17. post_data = (char*)malloc(post_length+1); // выделяем память для буфера,18. fread(post_data, post_length, 1, stdin); // читаем со стандартного ввода тело запроса,19. post_data[post_length] = 0; // завершаем строку нулевым байтом.20. }21. }22.23. // Выводим заголовок ответа...24. printf("Content-type: text/html\r\n\r\n");25.26. // и его тело:27. printf("<h1>Здравствуйте!</h1>\r\n");28.29. if (strlen(query_string)) {30. printf("<p>Параметры GET-формы: %s\r\n", query_string);31. }32.33. if (post_length) {34. printf("<p>Параметры POST-формы: %s (длина тела запроса: %d)\r\n", post_data, post_length);35. free(post_data); // не забываем освободить выделенную в строке 17 память36. }37.38. return 0;39.}Браузер в результате получит примерно следующий код (если "засабмитить" на эту программу POST-форму из последнего примера):<h1>Здравствуйте!</h1><p>Параметры POST-формы: name=Vasya&okbutton=OK (длина тела запроса: 22) Что при этом отобразится на экране пользователя, думаю, понятно без комментариев.Как видите, даже простейшая программа вывода параметров не очень проста. Более того, по стандарту HTTP почти все не алфавитно-цифровые символы (в т.ч. и русские буквы) передаются в UrlEncoded-виде (%XX, где XX - шестнадцатеричный код символа), и, если добавить в приведенную Си-программу код расшифровки UrlEncode, она уже не поместится на экран. А это - всего лишь базовые операции. А как вырастет программа на Си, если необходимо работать с базой данных?Впрочем, написание CGI-программ на Си - довольно редкое извращение. Чаще всего это делают на Perl - языке, разработанном специально для обработки текстовых данных, а наличие модуля CGI делает написание CGI-скриптов намного более простой задачей. Здесь я не буду Вас знакомить с Perl, отмечу лишь, что проблем остается достаточно: все же Perl не предназначен для Web, это язык универсальный. Да и сама технология CGI несовершенна: при каждом обращении происходит запуск программы (в случае с Perl - интерпретатор языка), а эта операция довольно ресурсоемкая: для домашней странички Васи Пупкина производительности, конечно, достаточно, но серьезный портал с десятками и сотнями тысяч хитов в сутки потребует уже огромных аппаратных мощностей.А теперь взглянем на веб-сервер Apache. По своей природе он модульный, и позволяет подключать расширения добавлением одной строки в конфигурационный файл. Было бы прекрасно, если бы существовал скриптовый язык, заточенный именно под Web, подключаемый модулем к Apache, не так ли? Это и есть PHP.В принципе, PHP можно скомпилировать и как CGI-приложение, и использовать так же, как и Perl - но это для нестандартных web-серверов или особых извращенцев.2. PHP: Препроцессор ГипертекстаВ 1994-м году программист по имени Rasmus Lerdorf, намучавшись с классическим перловым модулем CGI, решил написать несколько Perl-скриптов, чтобы было попроще создавать свою домашнюю страницу. Такой движок был готов к началу 1995 года и назывался Personal Home Page Tools (PHP). Умел он не очень много - понимал простейший язык и всего несколько макросов.Через некоторое время понадобилось обрабатывать формы, поэтому Rasmus Lerdorf и для увеличения производительности все переписал на C. Так появился к середине 1995 года Personal Home Page/Forms Interpreter (PHP/FI) 2.0. Приставка FI - присоединилась из другого пакета Rasmusa, который умел обрабатывать формы (Form Interpritator). PHP/FI компилировался внутрь Apache и использовал стандартный API Apache. PHP скрипты оказались быстрее аналогичных CGI - скриптов, так как серверу не было необходимости порождать новый процесс. Язык PHP по возможностям приблизился к Perl, самому популярному языку для написания CGI-программ. Была добавлена поддержка множества известных баз данных (например, MySQL и Oracle). Интерфейс к GD - библиотеке, позволял генерировать картинки на лету.Труды свои Rasmus Lerdorf, следуя принципам Open Source, выложил на всеобщее обозрение, и на некотором количестве сайтов PHP/FI вполне успешно использовался, хотя был довольно примитивен. С этого момента началось широкое распространение PHP/FI.В 1997-м на PHP/FI, в поисках инструмента для удобного web - программирования, наткнулись два других программиста - Andi Gutmans и Zeev Suraski. Идея им понравилась, но функциональность и скорость работы PHP/FI оставляли желать лучшего. Zeev Suraski и Andi Gutmans решили переписать внутренний движок для исправления ошибки интерпретатора и повышения скорости выполнения скриптов. 6 июня 1998 года вышла новая версия, которая была названа PHP 3. Язык получился универсальный и мощный, и вскоре привлек внимание множества web - разработчиков: к концу 1998 года PHP3 использовался на ~10% web - серверов. К лету 1999 года PHP 3 был включен в несколько коммерческих продуктов. По данным NetCraft на ноябрь 1999 PHP использовался в более чем 1 млн. доменах.Скромное название "Personal Home Page" уже не очень-то соответствовало реальности, и название было изменено на (в лучших Unix-традициях) рекурсивное: PHP: Hypertext Preprocessor. "Движок" PHP 4, названный Zend Engine, разрабатывался усилиями уже сформировавшегося и с тех пор непрерывно разрастающегося PHP community, и в 2000-м году вышла 4-я версия PHP, ставшая менее чем через полгода стандартом для web - программирования под Unix (и не только): каждый уважающий себя хостер предоставлял поддержку PHP. Сейчас разработан PHP5, основанный на новом Zend Engine 2...2.1. Что такое PHP?PHP - это скрипт-язык (scripting language), встраиваемый в HTML - код, который интерпретируется и выполняется на web - сервере. Проще всего это показать на примере:Листинг prim_1<html> <head> <title>Вас приветствует PHP</title> </head> <body> <?phpecho "Привет Виктор Сергеевич! Учи меня!";?> </body> </html>После выполнения этого скрипта получают страничку, в которой будет написано:Основное отличие от CGI-скриптов, написанных на других языках, типа Perl или C - это то, что в CGI-программах Вы сами пишете выводимый HTML-код, а, используя PHP - вы встраиваете свою программу в готовую HTML-страницу, используя открывающий и закрывающий теги (в примере <?php и ?>).Отличие PHP от JavaScript, состоит в том, что PHP-скрипт выполняется на сервере, а клиенту передается результат работы, тогда как в JavaScript-код полностью передается на клиентскую машину и выполняется только там.Любители Internet Information Server найдут, что PHP очень похож на Active Server Pages (ASP), а энтузиасты Java скажут, что PHP похож на Java Server Pages (JSP). Все три языка позволяют размещать код, выполняемый на Web-сервере, внутри HTML страниц.2.2. Возможности PHPНа PHP можно делать все, что можно делать с помощью CGI-программ: обрабатывать данные из форм, генерировать динамические страницы, получать и посылать куки (cookies). Кроме этого в PHP включена поддержка многих баз данных (databases), что делает написание web-приложений с использованием БД до невозможности простым.Вот неполный перечень поддерживаемых БД:|
Adabas D | InterBase | Solid | | dBase | mSQL | Sybase | | Empress | MySQL | Velocis | | FilePro | Oracle | Unix dbm | | Informix | PostgreSQL | | | | Вдобавок ко всему PHP понимает протоколы IMAP, SNMP, NNTP, POP3 и даже HTTP, а также имеет возможность работать с сокетами (sockets) и общаться по другим протоколам.2.3. Почему нужно выбирать PHPРазработчикам web-приложений нет необходимости говорить, что web-страницы - это не только картинки и текст. Достойный внимания сайт должен поддерживать достаточно высокий уровень интерактивности с пользователем: поиск информации, продажа продуктов, конференции и т.п.Традиционно все это реализовалось CGI-скриптами, написанными на Perl. Но CGI- скрипты очень плохо масштабируемы. Каждый новый вызов CGI, требует от ядра порождения нового процесса, а это занимает процессорное время и тратит оперативную память.PHP предлагает другой вариант - он работает как часть web-сервера, и этим самым похож на ASP от Microsoft.Синтаксис PHP очень похож на синтаксис C или Perl. Люди, знакомые с программированием, очень быстро начинают писать программы на PHP. В этом языке нет строгой типизации данных и нет необходимости в действиях по выделению/освобождению памяти.Программы, написанные на PHP, легко читаемы. PHP - код легко зрительно прочитать и понять, в отличие от Perl-программ.2.4. Недостатки PHPPHP является интерпретируемым языком, и как следствие этого, не может сравниться по скорости с компилируемым С. Однако при написании небольших программ, что и присуще проектам на PHP, когда весь проект состоит из многих небольших страниц с кодом, вступают в силу накладные расходы на загрузку в память и вызов CGI-программы, написанной на С.Не такая большая база готовых модулей, как, например, СPAN у Perl. С этим ничего нельзя поделать - это дело времени. В PHP 4 разработчики предусмотрели специальный репозиторий PEAR, аналогичный CPAN, и, конечно, очень скоро будет написано достаточное количество модулей для его наполнения. 2.5. Встраивание PHP в HTML - формуСначала изменим HTML-форму из предыдущего раздела. Для этого внесем некоторые изменения в файл form_1.html:<html><head> <title>Вас приветствует PHP</title> </head><body><form method="POST" action="form_handler.php">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" name="okbutton" value="OK"></form></body></html>PHP - код разместим в файле form_handler.php:<?echo "<h1>Привет, <b>" . $_POST['name'] . "</b></h1>!";?>PHP - скрипт заключен в специальные тэги <? и ?>, внутри которых использован для вывода текста оператор echo.Переменные GET-запроса попадают в массив $_GET, переменные POST-запроса - в массив $_POST, серверные переменные (типа IP-адреса, имени скрипта и т.д.) - в массив $_SERVER, оператор "точка" (.) - объединение строк... Причем все служебные операции (чтение stdin и переменных среды, Url-декодирование) уже произвел сам PHP. Удобно, не так ли? Далее. Зачем нам два файла - HTML с формой и PHP-скрипт? Вполне достаточно одного скрипта:Листинг form_2.html<html><head> <title>Вас приветствует PHP</title> </head><body><?if ($_SERVER['REQUEST_METHOD'] == 'POST') {echo "<h1>Привет, <b>" . $_POST['name'] ."</b>! Учите меня!</h1>";}?><form method="POST">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" name="okbutton" value="OK"></form></body></html>Из тэга form убрали атрибут action - это значит, что форма отправляется "сама на себя", т.е. на текущий URL. Это называют "postback form". С помощью оператора if проверяется, использован ли для загрузки документа метод POST, и - если это так - в следующей строке выводится приветствие. В окне браузера можно увидеть:2.6. HTML-формы. Массивы $_GET и $_POSTФормы являются основным способом обмена данными между web-сервером и браузером (пользователем). Формы выполняют главную функцию web - программирования: обеспечивают взаимодействие с пользователем.2.6.1. Особенности метода отправки формы POSTВозьмем уже знакомый по первой главе пример form_2.php и внесем в него некоторые изменения:Листинг form_3.php<html><head> <title>Вас приветствует PHP</title> </head><body><?if ($_SERVER['REQUEST_METHOD'] == 'POST') {echo '<h1>Привет, <b>' . $_POST['name'] . '</b>!</h1>';}?><form method="POST" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" name="okbutton" value="OK"></form></body></html>Форма, приведенная в строках 8-12 (выделено цветом), содержит два атрибута: name и okbutton:1. атрибут method указывает метод отправки формы POST;2. атрибут action, указывающий URL, на который отправляется форма, заполняется значением серверной переменной PHP_SELF - адресом выполняемого в данный момент скрипта.<?=$_SERVER['PHP_SELF']?> - сокращенная форма записи для echo: <? echo $_SERVER['PHP_SELF']; ?>. Если в поле форма name ввести, например, значение Вася, и нажать кнопку OK, то Браузер отправит после этого на сервер POST-запрос. Тело запроса имеет вид: name=Вася&okbutton=OK. PHP при этом автоматически заполнит массив $_POST:$_POST['name'] = 'Вася'$_POST['okbutton'] = 'OK'В действительности, значение "Вася" отправляется браузером в urlencode-виде; для кодировки windows-1251 это значение выглядит как %C2%E0%F1%FF. Но, поскольку PHP автоматически осуществляет необходимое декодирование, мы можем "забыть" об этой особенности - пока не придется работать с HTTP-запросами вручную.Так как в теле запроса указываются только имена и значения, но не типы элементов форм, PHP понятия не имеет, соответствует $_POST['name'] строке ввода, кнопке, или списку. Но эта информация нам, в общем-то, совершенно не нужна.Поскольку знать, что написано на кнопке submit, нам необязательно, в строке можно удалить атрибут name, сократив описание кнопки до <input type="submit" value="OK"> (листинг form_4.php). В этом случае, браузер отправит POST-запрос name=Вася.Листинг form_4.php<html><head> <title>Вас приветствует PHP</title> </head><body><?if ($_SERVER['REQUEST_METHOD'] == 'POST') {echo '<h1>Привет, <b>' . $_POST['name'] . '</b>!</h1>';}?><form method="POST" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" value="OK"></form></body></html>2.6.2. Особенности метода отправки формы GETА теперь подобные рассуждения проделаем для метода отправки формы GET:Листинг form_5.php<html><head> <title>Вас приветствует PHP</title> </head><body><?if (isset($_GET['name'])) {echo '<h1>Привет, <b>' . $_GET['name'] . '</b>!</h1>';}?><form action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" value="OK"></form></body></html><html><body><?if (isset($_GET['name'])) {echo '<h1>Привет, <b>' . $_GET['name'] . '</b></h1>!';}?><form action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><br><input type="submit" value="OK"></form></body></html>В строке 11 можно было бы написать <form method="GET">. Но GET - метод по умолчанию.Браузер отправляет GET-запрос, который равносилен вводу в адресной строке адреса: http://адрес-сайта/имя-скрипта.php?name=Вася:PHP с GET-формами поступает точно так же, как и с POST-формами, с тем отличием, что заполняет массив $_GET.Кардинальное же отличие - в строке 7. Поскольку простой ввод адреса в строке браузера является GET-запросом, проверка if ($_SERVER['REQUEST_METHOD'] == 'GET') бессмысленна: все, что в этом случае можно выяснить, что кто-то не отправил на скрипт POST-форму. Поэтому прибегают к конструкции isset(), которая возвращает true, если переменная определена (т.е. ей было присвоено значение), и false - если переменная не определена. Если форма была заполнена - как Вы уже поняли, PHP автоматически присваивает $_GET['name'] соответствующее значение.Способ проверки с помощью isset() - универсальный, его можно было бы использовать и для POST-формы. Более того, он предпочтительнее, так как позволяет выяснить, какие именно поля формы заполнены.Во многих старых книгах и статьях утверждается, что:1. Данные как из GET, так и из POST-форм попадают непосредственно в переменные (в нашем случае - $name), причем POST-данные приоритетнее, т.е. "затирают" GET-данные;2. Данные GET и POST-форм хранятся соответственно в массивах $HTTP_GET_VARS и $HTTP_POST_VARS.Эта информация устарела. Запомните этот момент, чтобы не попасть впросак со старыми скриптами или книгами.Немного более сложный пример.Листинг form_6.php<html><body><?if (isset($_POST['name'], $_POST['year'])) {if ($_POST['name'] == '') {echo 'Укажите имя!<br>';} else if ($_POST['year'] < 1900 || $_POST['year'] > 2004) {echo 'Укажите год рождения! Допустимый диапазон значений: 1900..2004<br>';} else {echo 'Здравствуйте, ' . $_POST['name'] . '!<br>';$age = 2004 - $_POST['year'];echo 'Вам ' . $age . ' лет<br>';}echo '<hr>';}?><form method="post" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><br>Введите Ваш год рождения: <input type="text" name="year"><input type="submit" value="OK"></form></body></html>Никаких новых приемов здесь не используется. Разберитесь, выполните код, попробуйте модифицировать...Изменим последний пример, чтобы пользователю не нужно было повторно заполнять поля. Для этого заполним атрибуты value элементов формы только что введенными значениями.Листинг form_7.php<html><body><?$name = isset($_POST['name']) ? $_POST['name'] : '';$year = isset($_POST['year']) ? $_POST['year'] : '';if (isset($_POST['name'], $_POST['year'])) {if ($_POST['name'] == '') {echo 'Укажите имя!<br>';} else if ($_POST['year'] < 1900 || $_POST['year'] > 2004) {echo 'Укажите год рождения! Допустимый диапазон значений: 1900..2004<br>';} else {echo 'Здравствуйте, ' . $_POST['name'] . '!<br>';$age = 2004 - $_POST['year'];echo 'Вам ' . $age . ' лет<br>';}echo '<hr>';}?><form method="post" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name" value="<?=$name?>"><br>Введите Ваш год рождения: <input type="text" name="year" value="<?=$year?>"><input type="submit" value="OK"></form></body></html>Несколько непонятными могут оказаться строки 4 и 5. Все очень просто: X = A ? B : C - сокращенная запись условия if (A) X=B else X=C. Строку 4 можно было бы записать так:if (isset($_POST['name'])) $name = $_POST['name'];else $name = '';Используемая в строках 21 и 23 конструкция <?=$foo ?> - и того проще: это сокращение для <? echo $foo ?>. Может возникнуть вопрос - почему бы не выбросить строки 4-5 и не написать:Введите Ваше имя: <input type="text" name="name" value="<?=$_POST['name']?>"><br>Введите Ваш год рождения: <input type="text" name="year" value="<?=$_POST['year']?>">Дело в том, что, если эти POST-переменные не определены (а так и будет, если форму еще не заполнили), то PHP выдаст предупреждения об использовании неинициализированных переменных (причем, вполне обоснованно).Такое сообщение позволяет быстро находить трудно обнаруживаемые опечатки в именах переменных, а также предупреждает о возможных "дырах" на сайте.Можно, конечно, поместить код с isset(). прямо в форму, но получится слишком громоздко.Разобрались? А теперь попробуйте найти ошибку в приведенном коде. Ну, не совсем ошибку, - но недочет.2.7. Функция htmlspecialchars()Не нашли? Я подскажу. Введите, например, в поле "имя" двойную кавычку и какой-нибудь текст, например, "123. Отправьте форму, и взгляните на исходный код полученной страницы. В четвертой строке будет что-то наподобие:Введите Ваше имя: <input type="text" name="name" value=""123">То есть - ничего хорошего. А если бы хитрый пользователь ввел JavaScript-код?Для решения этой проблемы необходимо воспользоваться функцией htmlspecialchars(), которая заменит служебные символы на их HTML-представление (например, кавычку - на "):Листинг form_7.php<html><body><?$name = isset($_POST['name']) ? htmlspecialchars($_POST['name']):'';$year = isset($_POST['year']) ? htmlspecialchars($_POST['year']) : '';if (isset($_POST['name'], $_POST['year'])) {if ($_POST['name'] == '') {echo 'Укажите имя!<br>';} else if ($_POST['year'] < 1900 || $_POST['year'] > 2004) {echo 'Укажите год рождения! Допустимый диапазон значений: 1900..2004<br>';} else {echo 'Здравствуйте, ' . $name . '!<br>';$age = 2004 - $_POST['year'];echo 'Вам ' . $age . ' лет<br>';}echo '<hr>';}?><form method="post" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name" value="<?=$name?>"><br>Введите Ваш год рождения: <input type="text" name="year" value="<?=$year?>"><input type="submit" value="OK"></form></body></html>Повторите опыт и убедитесь, что теперь HTML-код корректен.Запомните - функцию htmlspecialchars() необходимо использовать всегда, когда выводится содержимое переменной, в которой могут присутствовать спецсимволы HTML.2.8. Применение функции phpinfo() для отладкиФункция phpinfo() - одна из важнейших в PHP. Она выводит информацию о настройках PHP, значения всевозможных конфигурационных переменных...Почему она упоминается в главе, посвященной формам? Потому что функция phpinfo() - удобнейшее средство отладки.Функция phpinfo(), помимо прочего, выводит значения всех $_GET, $_POST и $_SERVER - переменных.Так что, если переменная формы "потерялась", самый простой способ обнаружить, в чем дело - воспользоваться функцией phpinfo(). Для того, чтобы функция выводила только значения переменных (и Вам не пришлось прокручивать десяток страниц), ее следует вызвать следующим образом:phpinfo(INFO_VARIABLES);или - что абсолютно то же самое:phpinfo(32);Листинг form_8.php<html><body><form method="post" action="<?=$_SERVER['PHP_SELF']?>">Введите Ваше имя: <input type="text" name="name"><input type="submit" value="OK"></form><?phpinfo(32);?></body></html>Или, например, такая ситуация: вы хотите узнать IP-адрес посетителя. Вы помните, что соответствующая переменная хранится в массиве $_SERVER, но - вот незадача - забыли, как именно переменная называется. Опять же, вызываем phpinfo(32);, ищем в табличке свой IP-адрес и находим его - в строке _SERVER["REMOTE_ADDR"]:3. Что такое MySQLMySQL - компактный многопоточный сервер баз данных. MySQL характеризуется большой скоростью, устойчивостью и легкостью в использовании.MySQL был разработан компанией TcX для быстрой обработки очень больших баз данных. Компания утверждает, что использует MySQL с 1996 года на сервере с более чем 40 БД, которые содержат 10.000 таблиц, из которых около 500 имеют более 7 миллионов строк (24.01.2004).MySQL является идеальным решением для малых и средних приложений. Исходники сервера компилируются на множестве платформ. Наиболее полно возможности сервера проявляются на Unix-серверах, где есть поддержка многопоточности, что дает значительный прирост производительности.На текущий момент MySQL все еще в стадии разработки, хотя версии 3.22 и более поздние полностью работоспособны.MySQL-сервер является бесплатным для некоммерческого использования. Для коммерческого использования необходимо приобрести лицензию, стоимость которой составляет 190 EUR.3.1. Возможности MySQLMySQL поддерживает язык запросов SQL в стандарте ANSI 92, и кроме этого имеет множество расширений к этому стандарту, которых нет ни в одной другой СУБД.Краткий перечень возможностей MySQL:? Поддерживается неограниченное количество пользователей, одновременно работающих с базой данных.? Количество строк в таблицах может достигать 50 млн.? Быстрое выполнение команд. Возможно MySQL самый быстрый сервер из существующих серверов.? Простая и эффективная система безопасности.MySQL действительно очень быстрый сервер, но для достижения этого разработчикам пришлось пожертвовать некоторыми требованиями к реляционным СУБД. В MySQL отсутствуют:? Поддержка вложенных запросов, типа SELECT * FROM table1 WHERE id IN (SELECT id FROM table2).? Не реализована поддержка транзакций. Взамен предлагается использовать LOCK/UNLOCK TABLE.? Нет поддержки триггеров и хранимых процедур.По словам создателей именно эти пункты дали возможность достичь высокого быстродействия. Их реализация существенно снижает скорость сервера. Эти возможности не являются критичными при создании web-приложений, что в сочетании с высоким быстродействием и малой ценой позволило серверу приобрести большую популярность.3.2. Примеры использования PHP совместно с MySQL3.2.1. Работа с формамиВ этом примере показано как в PHP легко обрабатывать данные с HTML - форм.Создадим HTML файл request.html.Листинг request.html<HTML><HEAD><TITLE>Запрос информации</TITLE><BODY><CENTER>Хотите больше знать о наших товарах?<P><TABLE WIDTH = 400><TR><TD align = right><FORM ACTION="email.php" METHOD="POST">Ваше имя:<BR> <INPUT TYPE="text" NAME="name" SIZE="20" MAXLENGTH="30"><P>Ваш email:<BR> <INPUT TYPE="text" NAME="email" SIZE="20" MAXLENGTH="30"><P>Меня интересуют:<SELECT NAME="preference"><OPTION value = "Яблоки">Яблоки<OPTION value = "Апельсины">Апельсины</SELECT><P><INPUT TYPE="submit" VALUE="Отправить запрос!"></FORM></TD></TR></TABLE></CENTER></BODY></HTML>В файле request.html указано, что данные формы будут обрабатываться файлом email.php. Приведем его содержание:Листинг email.php<?/* Этот скрипт получает переменные из request.html */PRINT "<CENTER>";PRINT "Привет, ".$_POST['name'];PRINT "<BR><BR>";PRINT "Спасибо за ваш интерес.<BR><BR>";PRINT "Вас интересуют ".$_POST['preference'].",информацию о них мы пошлем вам на email: ".$_POST['email'];PRINT "</CENTER>";?>Теперь, если пользователь вызовет request.html и наберет в форме имя “Вася”, email: vasya@pupkin.com и скажет, что его интересуют “Яблоки”, а после этого нажмет "Отправить запрос!",то в ответ вызовется email.php, который выведет на экран примерно следующее:Привет, ВасяСпасибо за ваш интерес.Вас интересуют Яблоки. Информацию о них мы пошлем вам на email: vasya@pupkin.comТеперь мы должны сдержать обещание и выслать email.Для этого в PHP есть функция MAIL.Синтаксис функция MAIL:void mail(string to, string subject, string message, string add_headers);to - email адрес получателя. subject - тема письма. message - собственно текст сообщения. add_headers - другие параметры заголовка письма (необязательный параметр).Допишем в конец файла email.php следующий код:Листинг добавочного кода для email.php<?php $subj = "Запрос на информацию"; $text = "Уважаемый ".$_POST['name']."! Спасибо за ваш интерес! Вас интересуют ".$_POST['preference']." Мы их распространяем бесплатно. Обратитесь в ближайший филиал нашей компании и получите ящик этого продукта."; mail($_POST['email'], $subj, $text); $subj = "Поступил запрос на информацию"; $text = $_POST['name']." интересовали ".$_POST['preference']." email-адрес: ".$_POST['email']; mail($adminaddress, $subj, $text); ?> Вот теперь пользователь будет получать письмо с более подробной информацией о наших товарах. Также письмо получит и администратор сайта. Когда интересующихся нашими товарами станет очень много, мы захотим их как-то упорядочить и хранить информацию о них в базе данных. Об этом в следующем примере. 3.2.2. Сохранение данных в базе данных MySQLДля начала создаем базу данных products и таблицу clients.Чтобы создать в системе базу данных, нужно войти в систему MySQL и ввести в командной строке MySQL: mysql> create database products; База данных создана: После этого следует набрать: mysql>use products; Следующий этап настройки базы данных -- создание таблиц. Это делается при помощи SQL-команды CREATE TABLE: CREATE TABLE clients ( name VARCHAR(25), email VARCHAR(25), choise VARCHAR(8) ); Таблицы базы данных созданы: Можно просмотреть перечень таблиц созданной базы данных c помощью оператора SHOW. Можно отобразить информацию о столбцах всех таблиц c помощью оператора DESCRIBE. Для просмотра данных, сохраненных в каждой таблице, можно применить оператор SELEKT. Все этапы создания базы данных с таблицами отражены на экране командной строки: Для общения с MySQL из PHP понадобятся следующие функции: 1. Создать соединение с MySQL. int mysql_connect(string hostname, string username, string password); Параметры функции: Hostname - имя хоста, на котором находится база данных. Username - имя пользователя. Password - пароль пользователя. Функция возвращает параметр типа int, который больше 0, если соединение прошло успешно, и равен 0 в противном случае. 2. Выбрать базу данных для работы. int mysql_select_db(string database_name, int link_identifier); Параметры функции: Database_name - имя базы данных. link_identifier - ID соединения, которое получено в функции mysql_connect. (параметр необязательный, если он не указывается, то используется ID от последнего вызова mysql_connect) Функция возвращает значение true или false 3. Функция выполняет запрос к базе данных. int mysql_query(string query, int link_identifier); Параметры функции: Query - строка, содержащая запрос link_identifier - см. предыдущую функцию. Функция возвращает ID результата или 0, если произошла ошибка. 4. Функция закрывает соединение с MySQL. int mysql_close(int link_identifier); Параметры функции: link_identifier - см. выше. Функция возвращает значение true или false Теперь файл email.php будет иметь следующий вид: Листинг email_1.php <? /* Этот скрипт получает переменные из request.html */ /* Переменные для соединения с базой данных */ $hostname = "localhost"; $username = "myusername"; $password = "mypassword"; $dbName = "products"; /* Таблица MySQL, в которой хранятся данные */ $userstable = "clients"; /* email администратора */ $adminaddress = "administration@me.com"; /* создать соединение */ mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение "); /* выбрать базу данных. Если произойдет ошибка - вывести ее */ mysql_select_db($dbName) or die(mysql_error()); echo "<CENTER>"; echo "Привет, ".$_POST['name']; echo "<BR><BR>"; echo "Спасибо за ваш интерес.<BR><BR>"; echo "Вас интересуют ".$_POST['preference'].". Информацию о них мы пошлем вам на email: ".$_POST['email']; echo "</CENTER>"; /* Отправляем email-ы */ $subj = "Запрос на информацию"; $text = "Уважаемый ".$_POST['name']."! Спасибо за ваш интерес! Вас интересуют ".$_POST['preference']." Мы их распространяем бесплатно. Обратитесь в ближайший филиал нашей компании и получите ящик этого продукта."; mail($_POST['email'], $subj, $text); $subj="Поступил запрос на информацию"; $text = $_POST['name']." интересовали ".$_POST['preference']." email-адрес: ".$_POST['email']; mail($adminaddress, $subj, $text); /* составить запрос для вставки информации о клиенте в таблицу */ $query = "INSERT INTO $userstable VALUES('$name','$email', '$preference')"; /* Выполнить запрос. Если произойдет ошибка - вывести ее. */ mysql_query($query) or die(mysql_error()); echo "Информация о вас занесена в базу данных."; /* Закрыть соединение */ mysql_close(); ?> Вот так можно работать с базой данных в PHP. Теперь кроме письменных уведомлений, информация о клиенте и его интересах будет заноситься в таблицу MySQL. 3.2.3. Получение (извлечение) данных из базы данных MySQLПосле занесения данных, нас иногда будет интересовать вопрос: так кого же из наших клиентов интересует товар “Яблоки”Напишем скрипт apple.php.Листинг apple.php<?/* Скрипт показывает клиентов, которые яблоки любят больше чем апельсины *//* Переменные для соединения с базой данных */$hostname = "localhost";$username = "myusername";$password = "mypassword";$dbName = "products";/* Таблица MySQL, в которой хранятся данные */$userstable = "clients";/* создать соединение */mysql_connect($hostname,$username,$password) OR DIE("Не могу создать соединение ");/* выбрать базу данных. Если произойдет ошибка - вывести ее */mysql_select_db($dbName) or die(mysql_error());/* составить запрос, который выберет всех клиентов - яблочников */$query = "SELECT * FROM $userstable WHERE choise = 'Яблоки'";/* Выполнить запрос. Если произойдет ошибка - вывести ее. */$res = mysql_query($query) or die(mysql_error());/* Как много нашлось таких */$number = mysql_num_rows($res);/* Напечатать всех в красивом виде*/If ($number == 0) {echo "<CENTER><P>Любителей яблок нет</CENTER>";} else {echo "<CENTER><P>Количество любителей яблок: $number<BR><BR>";/* Получать по одной строке из таблицы в массив $row, пока строки не кончатся */while ($row=mysql_fetch_array($res)) {echo "Клиент ".$row['name']." любит Яблоки.<BR>";echo "Его Email: ".$row['email'];echo "<BR><BR>";}echo "</CENTER>";}?>Вот и все, продукт практически готов.
|
|