Первый сайт на PHP

         

НЕМНОГО О WEB-ПРОГРАММИРОВАНИИ



НЕМНОГО О WEB-ПРОГРАММИРОВАНИИ

Все языки программирования, используемые при разработке web-сайтов, можно разделить на две большие группы.

К первой относятся те из них, код которых выполняется на компьютере посетителя сайта, т. е. в браузере, запущенном на компьютере пользователя. Это известные всем JavaScript и VBScript. Программы на этих языках встраиваются в код web-страниц или выносятся в отдельный файл, обращение к которому осуществляется из web-страницы (в этом случае браузер все равно обрабатывает такие «вынесенные» программы таким же образом, как если бы они были встроены в код страницы).

Во вторую группу включаются те языки, программы на которых выполняются на том компьютере, где расположен web-сервер. Эта группа более обширна - дело в том, что в принципе на web-сервере могут исполняться программы на любом языке, даже командных .bat-файлов MS-DOS, важно лишь, чтобы на нем была установлена программа-интерпретатор этого языка, удовлетворяющая стандарту CGI, которому также должен удовлетворять сам web-сервер.

РНР относится ко второй группе - программа на РНР исполняется на web-сервере. Однако от других CGI-языков РНР сильно отличается в лучшую сторону прежде всего своей простотой. При создании программы на РНР нет необходимости учитывать все те многочисленные мелочи, которые отравляют жизнь программистам на Perl или C++, - не надо заботиться о правах доступа к файлам сценария, не надо прописывать точные пути к различным модулям, нет необходимости следить за отсутствием в файле скрипта недопустимых символов. Синтаксис языка РНР допускает его легкое освоение как начинающим программистом, так и тем, кто уже использовал ранее какой-либо язык программирования. Можно целиком и полностью сосредоточиться на решаемой задаче и не думать о мелочах. Именно это и делает РНР подходящим выбором для web-дизайнера, который, начав его использовать, может вообще забыть о каких-либо других CGI-языках. (Впрочем, если исходить из механизма действия, то РНР более правильно называть не "CGI-языком", а препроцессором - что, собственно, отражено даже в его названии. В то время как CGI-приложение просто выдает некие данные в браузер посетителя, препроцессор просматривает все или некоторые файлы, выдаваемые web-сервером посетителю, и ищет в них определенные команды, которые и выполняет. Именно такой способ работы и позволяет указывать код программ на РНР непосредственно в тексте web-страниц.)


Одним из наиболее заметных достоинств РНР является возможность без особых затруднений работать с серверами баз данных. Ранее, до появления этого языка, задание, выражающееся словами "приделать базу данных к web-странице", было довольно трудным и малодоступным для начинающих web-дизайнеров. Приходилось либо самостоятельно разрабатывать хитроумные скрипты, взаимодействующие как с программой управления базой данных, так и с web-страницами сайта, либо закупать их у фирм-разработчиков. С помощью же РНР использование базы данных на сайте стало едва ли не элементарным. Для работы с подавляющим большинством типов баз данных в РНР есть встроенные функции, поэтому теперь достаточно лишь установить на web-сервере программу работы с базой данных (наиболее часто используется бесплатная MySQL - http://www.mysql.com) и включить в текст PHP-сценария команды работы с нею (их список приведен в описании языка вместе с примерами использования).

Возможности РНР можно весьма серьезно расширить с помощью дополнительных модулей, содержащих различные функции. Эти модули при необходимости размещаются на web-сервере, на котором установлен PHP-интерпретатор. Большое количество готовых модулей можно загрузить с адреса http://www.php.net, там же в разделе документации приведено и полное их описание. (В том web-сервере с установленным РНР, который распространяется с сайта http://php.spb.ru, никаких дополнительных модулей нет для уменьшения размера дистрибутива.) Например, модуль Zlib позволяет работать из программы на РНР с архивами в формате Gzip, а модуль libswf - с Flash-презентациями, создавая и редактируя их прямо из программы на РНР.


Вся информация о сервере и интерпретаторе - одной командой phpinfo()



Рисунок 1.1. Вся информация о сервере и интерпретаторе - одной командой phpinfo()




А это - русский сайт по РНРЯсно, коротко, доступно



Рисунок 2.2. А это - русский сайт по РНР. Ясно, коротко, доступно


Первым делом установите на своем компьютере web-сервер Apache из загруженного файла (этот процесс подробно описан на сайте Дмитрия Бородина, в статье по адресу http://php.spb.ru/php/install_module.html) и освойте его использование. В последнем нет ничего сложного - достаточно внимательно прочитать статью Дмитрия и файлы Readme из дистрибутива. После этого вы сможете полноценно работать с программами на РНР на своем компьютере, не выходя в Интернет, например, тестировать разработанные с использованием РНР сайты. (Версия РНР на сайте Дмитрия на момент написания этого текста была 4.0.6, в руководстве же рассматривается третья версия языка. Однако подавляющее большинство функций в третьей и четвертой версиях языка одинаковые, заметные различия есть разве что в технологии использования некоторых глобальных переменных и в наличии в 4-й версии механизма сессий - об этом будет рассказано в последующих главах.)

Ну а затем приступайте к изучению языка. В нескольких следующих главах изложены самые основные его понятия и описаны базовые команды, с помощью которых можно создать неплохие РНР-программы. За остальной информацией обращайтесь к описанию языка, тем более что оно переведено на русский язык и снабжено массой примеров кода. Только помните, что в том дистрибутиве web-сервера, о котором говорилось выше, отсутствуют модули, расширяющие возможности РНР, так что некоторые разделы описания будут неактуальны. Впрочем, ничего не мешает вам загрузить нужные модули отдельно и установить их (на сайте http://php.spb.ru описано, как это сделать), однако первое время такая необходимость у вас вряд ли появится.

Русскую версию учебника по РНР для версий 4.0 и выше вы можете загрузить как с сайта разработчиков РНР, так и с некоторых русских сайтов, например, с ресурса Александра Пирамидина -http://pyramidin.narod.ru.

Готовый к использованию web-сервер вместе с интерпретатором РНР, а также системой управления базами данных MySQL вы также можете найти на сайте проекта "Денвер", расположенном по адресу http://dklab.ru/chicken/web (Рисунок 2.3). В отличие от вышеупомянутого ресурса "РНР по-русски", ведущие проекта "Денвер" Дмитрий Котеров, Дмитрий Короленко, Игорь Светликов и Андрей Любченко регулярно обновляют свой проект, постоянно размещая на нем свежие версии web-сервера с набором компонентов. Однако установка "Денвера" более автоматизирована, нежели набора с сайта "РНР по-русски", и предусматривает значительно меньшую ее "управляемость".

"Денвер" можно порекомендовать тем, кто предпочитает автоматически получить на своем компьютере готовый к использованию web-сервер в целях изучения языка РНР и создания на нем программ, а "РНР по-русски" понравится тому, кто привык все, что ему надо, настраивать сам. Тем более что последнее будет весьма легко - достаточно внимательно прочитать комментарий Дмитрия с сайта и файлы Readme из дистрибутива.





Клуб РНРСпрашивайте и отвечайте



Рисунок 2.4. Клуб РНР. Спрашивайте и отвечайте


Подразделением "Клуба PHP-разработчиков" является сайт "РНР в деталях" (Рисунок 2.5) - http://detail.phpclub.net, на котором представлены готовые программы на РНР, а также немало интересных сведений по этому языку.

В Сети есть немало и других сайтов с информацией о РНР:

http://php.itsoft.ru,

http://virtual.bresttelecom.by/php,

http://www.providerz.ru/articles/php и другие.



МЕСТА



МЕСТА

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

В RuNet'e использовать РНР разрешается, например, на таких бесплатных серверах, как http://www.hl.ru, http://webservis.ru, http://wallst.ru, http://www.hut.ru, http://meridian.tomsk.ru, на иностранных - http://www.saxen.net и многих других. Однако, при выборе бесплатного хостинга для размещения сайта помните, что в подавляющем большинстве случаев вам придется в обязательном порядке размещать на своих страницах рекламные баннеры (за их показ на вашем сайте рекламодатели платят деньги компании, владеющей сервером хостинга. Эти деньги, собственно, и служат оплатой поддержки размещенных на этом сервере сайтов). Кроме того, весьма часто владельцы хостингов с поддержкой РНР и других CGI-языков запрещают размещать на сайтах, расположенных у них, файлы zip, rar, ехе, трЗ. Впрочем, последнее условие можно обойти, использовав для хранения таких файлов другой бесплатный сервер, - пусть и без поддержки РНР.

На рынке платного хостинга ситуация другая - сейчас уже трудно найти хостинг, где бы, наоборот, не предлагали использовать РНР. Тарифные планы, не предполагающие использование РНР, сохранились разве что у некоторых провайдеров услуг доступа в Интернет, параллельно предоставляющих и услугу размещения web-сайтов за отдельную плату. Так что для построения сайтов, использующих РНР, можно выбирать практически любой сервер платного хостинга, оценивая его по различным другим критериям (цена, надежность, скорость и т. д.). Достаточно трудно рекомендовать какую-либо определенную фирму, однако можете попробовать ValueHost (www.valuehost.ru), www.350mb.ru, www.net.ru и другие.



Официальный сайт РНР



Рисунок 2.1. Официальный сайт РНР


Однако тем, кто желает разработать сайт с применением РНР, возможно, лучше посетить прежде всего русский сайт "РНР по-русски" (Рисунок 2.2), расположенный по адресу http://php.spb.ru, и загрузить с него два файла - полное описание РНР на русском языке (перевод руководства по РНР с сайта www.php.net) и web-сервер Apache с РНР-мо-дулем, сконфигурированным для немедленного использования. Оба файла подготовил и разместил в Сети ведущий этого сайта Дмитрий Бородин.



PHP: ИСТОРИЯМЕСТАИСТОЧНИКИ



PHP: ИСТОРИЯ. МЕСТА. ИСТОЧНИКИ

В отличие от многих других языков программирования, РНР был создан не какой-либо корпорацией или гением-программистом, а обычным пользователем, Расмусом Лердорфом, в далеком 1994 году. Цель разработки языка была проста - сделать домашнюю страничку Расмуса более интерактивной, а значит, и более привлекательной для посетителей. Расмус разработал базовый синтаксис и написал первый интерпретатор своего языка, получившего название Personal Home Page Tools - т. е. РНР. Этот интерпретатор мог обрабатывать лишь несколько основных команд, однако начало было положено.

В 1995 году Расмус доработал интерпретатор РНР, соединив его с другой своей программой, умевшей обрабатывать HTML-формы (именовавшейся FI - от "Form Interpretator"), а также сделал так, что интерпретатор, получивший название PHP/FI Version 2, мог становиться частью web-сервера. Это новшество позволило программам на РНР исполняться очень быстро. Кроме того, в том же 1995 году интерпретатор РНР был дополнен возможностями1 обработки новых команд, в частности, команд для работы с серверами баз данных и автоматического создания gif-файлов (последнее, к примеру, может быть использовано для генерации кнопок-счетчиков посещений). PHP/FI был размещен в Сети для всеобщего использования, и началось его повсеместное распространение. К концу 1997 года РНР использовался более чем на пятидесяти тысячах сайтов.

Web-мастера быстро оценили достоинства нового языка web-программирования, такие как легкость освоения и богатство возможностей, и вскоре традиционные Perl и С стали сдавать свои позиции. Так как исходный код интерпретатора был открыт (а сам интерпретатор, понятно, бесплатен), то энтузиасты стали заниматься его доработкой, и летом 1998 года появился на свет РНРЗ - детище Зива Сураски и Энди Гутманса (Zeev Suraski and Andi Gutmans). РНРЗ был создан практически "с нуля", так как его авторы сочли код предыдущих версий недостаточно эффективным. Кроме того, РНРЗ стал весьма легко расширяемым продуктом. Любой, создавший на основе определенных стандартов модуль расширения РНР, позволяющий, скажем, работать с архивами какого-либо типа, мог этот модуль интегрировать с программными файлами РНР без каких-либо серьезных затрат времени и сил. Уже к концу 1999 года число сайтов, построенных на основе РНР, перевалило за миллион. Весьма важным достоинством РНР также являлось то, что программы, позволявшие обрабатывать команды РНР, были созданы практически для всех операционных систем, от Windows до Unix и Linux.

В 2000-м году вышла разработанная компанией Zend Technologies четвертая версия интерпретатора РНР, дополненная множеством новых функций. В настоящее время именно она является наиболее распространенной - РНР используется более чем на 20% сайтов Сети. Сейчас готовится уже пятая версия данного языка.



PHP в деталяхДля тех, кому мало ответов в форумах



Рисунок 2.5. PHP в деталях. Для тех, кому мало ответов в форумах




Проект "Денвер"



Рисунок 2.3. Проект "Денвер"


Для написания кода на РНР подходит любой текстовый редактор -от "Блокнота" до "Script Editor" из пакета Microsoft Office, здесь выбор зависит от вашего личного вкуса и желания.



РНР В РОССИИ



РНР В РОССИИ

Основной русский ресурс по РНР - это, несомненно, сайт Дмитрия Бородина "РНР для всех" (http://php.spb.ru, зеркало -http://rusphp.chat.ru), о котором уже упоминалось выше. Его содержимого практически достаточно для начала работы и изучения основ РНР, поэтому его посещение весьма и весьма желательно.

Другим большим порталом, посвященным РНР, является "Клуб РНР-разработчиков" (http://www.phpclub.net). Там вы найдете множество примеров сценариев на РНР, сможете загрузить литературу на русском языке. Форум разработчиков на РНР (Рисунок 2.4), размещенный на этом сайте, даст вам возможность получить от профессионалов в web-программировании ответ на свой вопрос, принять участие в каком-либо обсуждении или пообщаться с коллегами в чате. Архив Форума содержит в себе ответы практически на все возможные вопросы по web-программированию на РНР. Также в "Клубе РНР-разработчиков" регулярно публикуются новости мира РНР-программирования, рассказывается о новых разработках в этой области, размещается информация о вакансиях web-дизайнеров и программистов на рынке труда.



С ЧЕГО НАЧАТЬ?



С ЧЕГО НАЧАТЬ?

Основным источником сведений по РНР является официальный сайт его разработчиков - www.php.net (Рисунок 2.1). Именно на этом сайте представлены дистрибутивы различных версий РНР для различных платформ. Также на www.php.net размещаются руководства по РНР на разных языках, а, кроме того, - списки сайтов, посвященных программированию на РНР.



PHP: ОСНОВЫ



PHP: ОСНОВЫ

Синтаксис PHP довольно простой. Программы на РНР встраиваются в текст web-страницы так же, как и сценарии на JavaScript, VBScript, при помощи окаймляющих угловых скобок с вопросительными знаками и указанием языка:

<?php

...

текст программы
...

?>

Команды РНР обязательно разделяются символом точки с запятой - ";" (символ конца абзаца или конца строки не учитывается никак), после последней в программе команды его можно не ставить. Также символ ";'' не ставится после условных операторов (if, switch) и операторов цикла (for, while и других).

Пример программы на РНР - на Рисунок 3.1.



Пример PHP-кодаПосмотрите внимательно



Рисунок 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. Каждый элемент формы может иметь свое имя.

Наиболее важным свойством формы является то, что в ее заголовке в открывающем тэге <f orm...> можно указать адрес какого-либо файла. В этом случае при загрузке этого файла в программный код, если он будет там присутствовать, передадутся значения всех переменных, установленных в этой форме, в частности, значения всех элементов формы, как если бы эти значения были установлены в программе, расположенной в самом загружаемом файле. Таким образом можно передавать значения переменных между различными 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. Отличие этих массивов от предыдущих состоит в том, что их переменные доступны еще и во всех функциях, расположенных в программе РНР, т. е. они являются глобальными.



З.1Программа на РНР (выделена жирным) в тексте web-страницы



Рисунок З.1. Программа на РНР (выделена жирным) в тексте web-страницы


Как и во всех языках программирования, в РНР есть возможность работать с переменными - некими объектами, имеющими имя и могущими принимать различные значения. Однако работа с переменными в РНР, пожалуй, самая легкая из всех возможных. Переменные не надо заранее объявлять (если не знаете, что это такое - то пока и не надо), разве что за исключением использования их в функциях. Для введения новой переменной достаточно просто присвоить ей какое-либо значение, а для помещения значения переменной в строку текста, имени файла или параметра команды, нужно просто написать ее имя в том месте, где должно быть ее значение. Чтобы РНР мог отличать переменные от строк или команд, имя переменной должно начинаться со знака доллара - ("$") и не должно содержать пробелов, знаков апострофа и некоторых других символов. При анализе программного кода интерпретатор РНР считает именем переменной все, что содержится между $ и ближайшим к нему символом, недопустимым в имени переменной.

В качестве имен переменных можно также использовать другие переменные - для этого другую переменную следует просто указать на месте имени первой: $$а.

Переменные в РНР могут быть четырех типов - число (целое и дробное), строка текста, массив и объект1. Интерпретатор РНР автоматически определяет тип переменной на основании анализа ее содержимого. Подробнее о типах данных вы можете узнать в руководстве по РНР (например, в том, что доступно с сайта "РНР по-русски"), там же рассказано и об особенностях работы с массивами (и вообще объяснено, что это такое, если вы еще не знаете).

Для включения числовой или строковой переменной в строку текста достаточно просто поместить переменную туда, где она должна стоять в этой строке. Например, в итоге выполнения кода $а="птица певчая"; $b="Дятел - $а"; переменной $b будет присвоено значение "Дятел - птица певчая".

Помните, что в РНР нельзя для сложения строковых переменных использовать символ "+" - он пригоден лишь для числовых выражений. Поэтому необходимо помещать переменные в строки или использовать команду конкатенации (точку): $с = $а. $b.


Есть еще два типа переменных - PDF-документ и PDF-инфо, но они применяются только при работе с файлами PDF (и при установленном модуле поддержки PDF).

Довольно часто используются сокращенные обозначения арифметических действий над переменными и действий по присваиванию им каких-либо значений. Например, команда $а+=3 означает, что переменную $а надо увеличить на 3, что и будет сделано, если она имеет числовой формат. Точно так же команда $а- = 3 уменьшает переменную $ а на 3, а команды $а*=2 и $а/=2 соответственно умножают и делят на два переменную $а. Команда $а.=" строка" эквивалентна команде $а="$а строка".

В РНР применяются также операции инкремента и декремента -т.е. изменения значения переменной на 1. Так, команды $а++ и $а-- соответственно увеличивают и уменьшают значение переменной $а на единицу. То же самое делают и команды ++$а, --$а, однако, в том случае, если подобная команда используется в выражении, они, в отличие от предыдущих, сначала изменяют значение переменной, а потом выдают его в выражение. Иными словами, если переменная $а равна 2, то после выполнения команды $b=$а++; ее значение достигнет 3, а $b будет установлена в 2. В то же время команда $b= + + $а; установит обе переменные в 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 имя (переменные, в которые записываются передаваемые параметры, и их тип) {...команды функции . . . }, а вызвать - простым указанием имени этой функции и параметров.


Чтобы просмотреть лишь избранные альбомы, достаточно их отметить...



Рисунок 4.1. Чтобы просмотреть лишь избранные альбомы, достаточно их отметить...


Кнопка, вызывающая переход на страницу, указанную в параметре action заголовка формы, должна иметь тип submit, например:

<input type=submit value="Вывести оглавления отмеченных альбомов">.



Если вас заинтересовали лишь отдельные вопросы, нет надобности загружать всю страницу



Рисунок 4.3. Если вас заинтересовали лишь отдельные вопросы, нет надобности загружать всю страницу


Данную схему, разумеется, можно доработать. Опыт показывает, что посетители чаще всего предпочитают просмотреть либо два-три выбранных раздела, либо все разделы сразу. В последнем случае им придется отмечать все checkbox'bi страницы, что занимает время и силы. Поэтому стоит поместить на страницу еще и кнопку вывода сразу всех разделов - "Просмотреть все". Ей можно назначить гиперссылку с адресной строкой, содержащей все переменные в значении on, а можно немного доработать код РНР на странице-обработчике запроса, попросту добавив во все условия проверку значения еще одной, общей для всех условий переменной: if (($bar02==True) ($all==True)) {... (напоминаю, что знак означает "или"), и тогда гиперссылка может вести всего лишь на адрес albm.php?all=True.

Можно для решения той же задачи поместить на страницу пару сценариев на JavaScript, выполняющих соответственно отметку всех checkbox'oв и, наоборот, их очистку. Так что простор для творчества имеется, и немалый.



РНР: ВЫБОРОЧНАЯ ЗАГРУЗКА



ГЛАВА 4. РНР: ВЫБОРОЧНАЯ ЗАГРУЗКА

В этой главе приведен пример простого 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.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) - отметив интересующие вопросы на странице раздела, можно получить подробные консультации исключительно по выбранным темам. Полученная страница и загрузится быстрее, да и при ее распечатке лишней бумаги тратить не потребуется.



ДОБАВЛЕНИЕ ТОВАРА



ДОБАВЛЕНИЕ ТОВАРА

Для добавления в магазин нового товара необходимо:

вставить на страницу его описание и тэг <select...> с кодом этого товара;

добавить в сценарий-калькулятор новые элементы массивов кодов и цен товаров - можно просто в конец;

добавить в сценарии-обработчике строчку, вставляющую в текст письма название товара согласно его коду.



Интернет-магазинПоле заказа количества товара



Рисунок 5.4. Интернет-магазин. Поле заказа количества товара


Также в форме должны присутствовать поля ввода контактной информации - см. на Рисунок 5.1. Скажем, текстовая строка типа text с именем e-mail - для адреса электронной почты и поле ввода текста textarea с именем contact - для ввода контактных данных (что сочтет нужным покупатель - имя, телефон, домашний адрес).

<input name="email" type="text">
<textarea name="contact" cols="30" rows="5" wrap="virtual">

</textarea>

(В параметре cols тэга textarea указывается количество символов, которое должно помещаться в одну строку в поле ввода текста, в параметре rows - количество строк текста, которые можно будет вписать в поле ввода до появления полос прокрутки. Параметр wrap="virtual" разрешает автоматический перенос текста на следующие строки в поле ввода.)

Разумеется, в форме должна быть кнопка ее отправки

<input type=submit>

и закрывающий тэг формы

</form>



КАЛЬКУЛЯТОР



КАЛЬКУЛЯТОР

Калькулятор для отображения на странице витрины информации о сумме заказа сделан на Javascript. Его текст приводится ниже. Но, так как книга посвящена РНР, а не Javascript, к его командам даны лишь минимально необходимые комментарии. Просто поместите код сценария в тексте web-страницы, набрав его с клавиатуры или отсканировав страницы книги.

В раздел <head> страницы с витриной следует поместить сценарий:

<SCRIPT LANGUAGE="JavaScript">

function calc()

{

В следующей строчке производится задание массива кодов товаров, встречающихся на web-странице и подлежащих учету. В ней должны быть перечислены все встречающиеся на странице коды товаров. Порядок перечисления кодов товаров не важен и не зависит от их порядка следования содержащих их элементов <select...> на самой странице.

tov=new Array("TOV1", "TOV2", "TOV3", "T0V4");

В другой такой же строчке перечисляются цены на эти товары точно в том порядке, в каком перечислялись коды товаров - на одних и тех же порядковых местах должны стоять код и цена, принадлежащие одному и тому же товару.

prc=new Array (100, 200, З00, 400);

Сценарий продолжается...

var kolvo=0;

var stoim=0;

for (n=0; n<tov.length; n++)

{

if (document.mainform(tov[n])!=null)

{

kolvo=kolvo+l*document.mainform(tov[n]).value;

stoim=prc[n]*document.mainform(tov[n]).value+stoim;

mess.innerНТМL="Количество заказанных товаров -"+kolvo+"<br>"+"CTOИMOCTb заказанных товаров -"+stoim;

document.mainform("stoim").value=stoim; document.mainform("kolvo").value=kolvo;

} </SCRIPT>

Вкратце можно сказать, что этот сценарий при своем запуске просматривает значения всех элементов форм на web-странице, имеющих перечисленные в массиве tov имена (а, как вы помните, в этом массиве перечислены коды товаров: т. е. элементы с этими именами - это соответствующие этим товарам выпадающие списки <select...>), и вычисляет сумму этих значений (общее число заказанных товаров) и сумму произведений этих значений на соответствующее каждому коду число из массива ргс - списка цен (т. е. считает общую сумму покупки). Полученные значения помещаются в элементы web-страницы с именем mess (текстовое сообщение), stoim (стоимость заказа), kolvo (количество заказанных единиц товара) (Рисунок 5.7).



Калькулятор стоимости



Рисунок 5.7. Калькулятор стоимости


В каждый тэг <select...>, присутствующий на странице и предназначенный для заказа товара, добавьте команду, предписывающую браузеру выполнять сценарий calc при каждом изменении значения элемента, отображаемого этим тэгом:

<select name=TOV1l onchange=calc ()>
<option value=0>0

...

</select>

В том месте страницы, где вы желаете отображать посетителю сведения о заказе, поместите строчку с элементом <р> или <div>, имеющую идентификатор mess - тот же, что упоминался в сценарии (здесь надо использовать именно параметр id, а не nаmе):

<р align=center id=mess> Информация о заказе появится здесь</р>

Где-нибудь в форме также поставьте два скрытых поля:

<input type=hidden name=stoim value=0>

<input type=hidden name=kolvo value=0>

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

Чтобы последнее произошло, команду, составляющую текст письма в сценарии на странице-обработчике формы, измените так, чтобы она включала в этот текст и значения переменных из скрытых полей:

$zak="C адреса $email от заказчика с контактными данными $contact пришла заявка на приобретение товара: \n$zак\пКоличество заказанных товаров -$kolvo\n О6щая стоимость заказа - $stoim";



ОТПРАВКА ЗАКАЗА



ОТПРАВКА ЗАКАЗА

После оформления заказа и нажатия посетителем кнопки отправки формы произойдет переход на страницу, указанную в заголовке этой формы (в рассматриваемом сценарии - zakaz.php). Именно в этом файле содержится программа отправки заказа.

При передаче формы сценарию на РНР содержимое каждого элемента переданной формы (для поля ввода текста - введенный текст, для элемента <select. . .> - значение параметра value выбранного пункта <орtion>) помещается в переменную, имя которой равно значению параметра пате данного элемента (Так происходит, если в файле pkp.mi установлен в on параметр register_globals). Кроме того, все эти значения помещаются в одноименные соответствующим значениям параметров пате элементы массива $HTTP_POST_VARS (если форма передана методом POST) или $HTTP_GET_VARS (если форма передана методом GET) (Так происходит, если в файле php.ini установлен в on параметр track_vars), а в РНР версии 4.1 и выше - еще и в массивы $_POST и $_GET соответственно. Например, значение элемента <select name="TOV1"> будет доступно сценариям на странице-обработчике в переменной $TOV1 и в элементе массива $HTTP_POST_VARS [ "TOV1' ] (а в РНР версии 4.1 и старше - еще и в элементе массива $_POST [ ' T0V1' ].

Однако особенностью использования этих массивов в частности является то, что для присоединения значения любого их элемента к какой-либо строковой переменной нельзя просто поместить их внутрь текста строки - нужно использовать оператор сложения строк: точку. Скажем, написать

$zak="$zak $HTTP_POST_VARS['TOV1']";

нельзя - надо использовать формат

$zak="$zak "$HTTP_POST_VARS['TOV1'];

Отправка письма осуществляется командой mail, как вы помните, имеющей формат

тай ("Кому", "Тема", "Текст сообщения", "Дополнительныезаголовки");

При выполнении данной команды на сервере формируется электронное письмо в соответствии с указанными параметрами и отправляется с помощью установленной на web-сервере почтовой программы (Вы можете установить такую программу и на своем компьютере - используйте, например, Office Mail Server Юрия Кучуры (доступен с http://eu3eu.chat.ru) или Courier Mail Server Романа Ругаленко (доступен с http.V/courierms. narod. ru)).


В качестве параметра "Кому" может выступать набор адресов, разделенных запятыми.

"Дополнительные заголовки" могут быть любые из допустимых почтовыми протоколами, разделяться они должны комбинацией символов /п, которая в РНР означает перевод строки. Если среди "Дополнительных заголовков" не указано поле From, то оно заполняется по умолчаниюпочтовой программой, установленной на web-сервере, например, именем "Unprivileged User".

Для отправки письма с заказом необходимо приготовить его текст. Можно, конечно, просто включить в письмо значения всех переменных с именами, равными кодам товара (т. е. полученные из элементов <select...>), и в конец добавить контактные данные посетителя. Но куда как лучше, чтобы владелец web-сайта получал не набор кодов, которые он еще должен по своим данным перевести в названия, а уже готовый список заказанных посетителем товаров (Рисунок 5.5). Для этого в текст сценария включим блок определения полного названия товара по его коду.


ПЕРСПЕКТИВЫ



ПЕРСПЕКТИВЫ

Вот так, очень просто, вы можете сделать элементарный Интернет-магазин. Конечно, небольшой - всего на одной странице. Но заказать представленный на этой странице товар и отправить заказ владельцу посетитель сможет.

При работе с таким Интернет-магазином посетителю даже не нужно быть постоянно подключенным к Интернету во время оформления заказа - он спокойно может загрузить страницу с перечнем товаров, отключиться от Сети, выбрать нужные предложения и заполнить поля формы заказа, а затем, подключившись снова, этот заказ отправить. Да и саму страницу со списком ему необязательно получать именно из Сети - вы можете отправить ее кому-либо по почте или поместить на компакт-диски, раздаваемые друзьям или коллегам (только не забудьте в этом случае указать в заголовке формы полный адрес страницы с обработчиком заказа, а не только ее имя).



PHP: ПРОСТЕЙШИЙ ИНТЕРНЕТ-МАГАЗИН



PHP: ПРОСТЕЙШИЙ ИНТЕРНЕТ-МАГАЗИН

С помощью РНР можно легко сделать мини-Интернет-магазин -т. е. установить на сайт форму заказа, которая будет отправляться вам по электронной почте. При этом почтовая программа посетителя использоваться не будет - ему даже необязательно вообще ее иметь.

К примеру, такой "магазин" сделан на странице http://www.harchikov.ru/cass.php (Рисунок 5.1). В этой главе рассказывается о его устройстве.



Письмо с заказомУдобно читать - удобно выполнять



Рисунок 5.5. Письмо с заказом. Удобно читать - удобно выполнять


Итак, в любом месте файла-обработчика формы, но лучше всего в начале, следует поместить следующий сценарий:

<?php
$zak="";

(В эту переменную будем последовательно собирать названия заказанных товаров.)

if ($TOV1>0){$zak="$zak Название товара 1 -$TOV1 шт.\n"; }

if ($TOV2>0){$zak="$zak Название товара 2 -$TOV2 шт.\n"; }

...

И такие же строчки - для каждого товара. В качестве имени переменной в условной части блока if ($ . . . >0) указывается значение параметра пате соответствующего тэга <select. . .>, а в последующих фигурных скобках - название того товара, к которому этот тэг относился на странице-витрине. В результате в том случае, если посетитель изменил значение какого-либо выпадающего списка на число, отличное от нуля, то в переменную Szak, которая впоследствии станет текстом отправляемого письма, включается название товара, соответствующего этому выпадающему списку, и сведения о количестве его заказанных единиц - та величина, которая в конце концов и оказалась значением этого выпадающего списка.

Теперь завершим составление текста письма:

$zak="C адреса $email от заказчика с контактными данными $contact пришла заявка на приобретение товара: \n$zak";

и отправим письмо-заявку:

mail ("электронный адрес владельца сайта", "Заказ на товар", $zak, "From: $email\nReply-To: $email\nContent-Type: text/plain; charset=windows-12 51");?>

В результате выполнения этой команды тот, кто обрабатывает заказы, получит аккуратный список заказанных товаров и сведения о заказчике (см. Рисунок 5.5). Причем если посетитель правильно ввел свой е-mail, то для связи с ним после получения письма достаточно нажать кнопку "Ответить" или ей подобную в почтовом клиенте - этот e-mail подставляется в заголовок письма From:.

Письмо будет отправлено через почтовую программу, находящуюся на сервере - программы на компьютере посетителя никак не будут затронуты.

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



ПРОЕКТ



ПРОЕКТ

Из каких же компонентов web-магазин должен быть сделан?

Отобразить ассортимент из пары десятков товаров можно на одной web-странице. На ней же можно разместить "калькулятор" и форму ввода контактных данных.

Раздел страницы, относящийся к одному товару, должен быть снабжен чем-то, что могло бы позволить посетителю как-нибудь этот товар отметить. Для последнего лучше всего использовать выпадающий список (Рисунок 5.2 - наподобие того, в котором устанавливается размер шрифта в Word): он заодно дает посетителю возможность выбрать и количество товара для заказа. На HTML для отображения такого списка необходимо использовать элемент <select паmе="имя этого элемента формы" >, внутри которого размещены тэги <ор-tion. . . >, в которых и указаны те значения, что в меню отображаются. При отправке формы странице-обработчику сценарию на ней передается переменная с именем, равным имени элемента <select...> и значением, равным числу из параметра value того тэга <option...>, который был посетителем выбран.



Реально действующий Интернет-магазин, построенный по описанной в этой главе схеме



Рисунок 5.1. Реально действующий Интернет-магазин, построенный по описанной в этой главе схеме




Виды полей ввода текста



Рисунок 5.3. Виды полей ввода текста


Форма, в которую посетитель внесет сведения о своем заказе и свои контактные данные, должна быть отправлена владельцу сайта. Для этого на странице, указанной в заглавии формы как ее обработчик; нужно разместить сценарий, собирающий значения всех элементов формы в единую текстовую строку и отправляющий эту строку на e-mail владельца сайта. Последнее сделать можно командой PHP mai 1 ().

Итак, весь Интернет-магазин будет состоять из двух файлов: витрины и обработчика заказа. Однако практически все возможности для торговли будут иметься: и список товаров, и возможность указания вида и количества заказываемого товара.

"Калькулятор", о желательности которого упоминалось на предыдущем шаге проектирования, можно сделать на JavaScript. Программа должна отслеживать изменения в выпадающих списках, сверяться со списком цен и в соответствии с данными этого списка выводить посетителю сообщение о стоимости его заказа. Вывод сообщения лучше всего сделать с помощью средств Dynamic HTML, динамически изменяя содержимое страницы.



ВИТРИНА



ВИТРИНА

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

В начале страницы, после тэга <body>, но до каких-либо описаний товаров, должен находиться заголовок формы:

<FORM METHOD="post" ACTION="zakaz.php"
NAME="mainform">

Допустим, что PHP-программа, обрабатывающая форму, находится в файле zakaz.php (и именно на эту страницу произойдет переход после нажатия кнопки типа submit в форме). Не забудьте указать параметр пате в заголовке формы - он потом пригодится для использования в коде калькулятора стоимости заказа. (Кстати, обратите внимание, что так как для передачи данных формы используется метод POST, а не GET, то при этом в адресной строке данные полей формы отображаться не будут.)

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

<select name="TOV1">
<option value=0>0</option>

<option value=1>1</option>
<option value=2>2</option>

...

<option value=10>10</option>
</select>

Обратите внимание, что первым по счету в выпадающем списке должно стоять значение 0 - именно оно будет отображаться по умолчанию.



Выпадающее меню



Рисунок 5.2. Выпадающее меню


Скажем, список на Рисунок 5.2 может отображаться, например, кодом

<select name=spis>

<option value=45>Пepвым</option>

<option value=81>Bторой</option>

<option value=31>Tpетий</option>

</select>

В зависимости от того, какой пункт списка будет выбран посетителем, сценарию-обработчику передастся в качестве значения переменной $spis (и элемента массива $HTTP_POST_VARS [ ' spis ' ]) то число, которое находилось в параметре value тэга <option>, отображающего выбранный пункт.

Для ввода посетителем контактных данных можно использовать элемент <textarea. . . >, позволяющий помещать в себя достаточно длинные фрагменты текста на нескольких строках (например, почтовый адрес), а для ввода адреса электронной почты - элемент типа text (он отображает однострочное поле для ввода текста), Рисунок 5.3.



предоставлять посетителю возможность осмотреть ассортимент



ЗАДАЧИ

Что, собственно, должен делать Интернет-магазин? Пожалуй, следующее:
предоставлять посетителю возможность осмотреть ассортимент товаров;
позволить посетителю как-нибудь отметить нужные товары;
принять у посетителя его контактные данные;
передать владельцу магазина список заказанных товаров и контактные данные посетителя. Причем весьма желательно, чтобы этот список был в удобочитаемом виде - чтобы выполнять заказ можно было сразу после его получения, не тратя время, скажем, на расшифровку кодов товаров.
Кроме того, весьма желательно предоставить посетителю нечто вроде "мини-калькулятора", который бы автоматически подсчитывал сумму заказа и отображал бы ее на web-странице - дабы посетитель мог рассчитывать заказ, исходя из своих финансовых возможностей.

Собственно, на первое время этого и достаточно.

Заказ сделан - можно уходить и ждать...



Рисунок 5.6. Заказ сделан - можно уходить и ждать...


В приведенном сценарии вместо одноименных элементов формы переменных можно использовать и соответствующие элементы массивов $HTTP_POST_VARS и (в РНР версии старше 4.1) SPOST. Например, строка добавления в текст заказа нового товара будет выглядеть как

if ($HTTP_POST_VARS['TOV1']>0){$zak="$zak Название товара 1 -

".$HTTP_POST_VARS['TOV1']." шт.\n"; }

строка генерации письма - как

$zak="C адреса ".$HTTP_POST_VARS['email']. " от заказчика с контактными данными

".$HTTP_POST_VARS['contact']." пришла заявка на приобретение товара:\n$zak";

и команда отправки письма - измененная по тому же принципу.



РНР:ПАПКОПОТРОШИЛКА



ГЛАВА 6. РНР:ПАПКОПОТРОШИЛКА

При создании Интернет-ресурса, содержащего часто обновляющееся однотипное содержание, проблема быстроты и удобства обновления встает достаточно остро. Например, вы являетесь администратором сайта, на котором размещаются статьи разных авторов. В таком случае при поступлении новой статьи вам приходится, помимо размещения на web-сервере (или выделенном вам аккаунте) ее самой, еще и обновлять страницу со списком этих статей, добавив ссылку на новоразмещенную web-страницу со статьей - иначе ведь попасть на новую статью с сайта будет невозможно. А если статьи поступают часто? Да еще и не только поступают, но и удаляются, или в них меняется название? Тогда ведь для отслеживания правильности содержания приходится прилагать немало усилий.

Или другая ситуация - необходимо разместить на сайте новостную ленту. Простое решение напрашивается сразу: просто включать текст новостей в содержащую их страницу. Или, в.крайнем случае, писать новости в отдельном файле, а в web-страницу включать этот файл с помощью команды PHP include - тогда при обновлении новостей придется загружать на сервер только файл с новостями, а не всю страницу. Но все же... не так это и удобно! Каждый раз работать с файлом с гипертекстовой разметкой, каждый раз его загружать на сайт... А если вам надо поручить загрузку человеку, который совершенно не знает HTML? Текст-то он напишет, а вот вставить его в нужное место гипертекстовой разметки?

Или, наконец, третья ситуация - вы делаете файловый архив, и ваши друзья загружают на ваш сервер свои файлы. Как сделать так, чтобы они появлялись в списке доступных для посетителей файлов сразу же после их загрузки, без вашего участия, без необходимости вручную обновлять их список?

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


Итак - вот сценарий:
<?php
Сначала укажем сценарию имя папки, в которой содержатся подлежащие каталогизации или включению в другую страницу файлы:
$dirct="new";
Для того чтобы РНР мог работать с файлами из этой папки, необходимо указать ее дескриптор - некое "внутреннее имя", "поток вывода данных" (о том, почему приходится так делать, смотрите литературу по РНР и программированию, пока же просто примите к сведению). Для этого используется функция opendir (каталог), а получаемый с ее помощью дескриптор записывается в переменную $hdl:
$hdl=opendir($dirct);
Теперь запишем все имена содержащихся в ней файлов в массив $а [ ]. Согласно синтаксису РНР (см. гл. 3), для этого достаточно просто присваивать массиву $а [ ] различные значения - при этом автоматически в него будут добавляться новые члены, которым эти значения будут присваиваться. Для помещения имен файлов (с расширениями) из директории $dirct в массив используется функция readdir (имя каталога), работающая с дескриптором этой директории, записанным ранее в переменную $hdl с'помощью функции opendir.
Комментарий:

Функция readdir предназначена для вывода списка файлов и папок, содержащихся в указанном в ее параметре каталоге. При каждом своем вызове она выдает имя случайно выбранного файла (или вложенной папки) указанного каталога, каждый раз - новое, до тех пор, пока не перечислит имена всех файлов и вложенных папок.
Среди выданных функцией readdir имен будут и ссылки на текущий и родительский (т. е. включающий в себя текущий) каталог, обозначаемые соответственно одной и двумя точками (так уж работает web-сервер). Поскольку нас интересуют только файлы каталога, то данные ссылки из списка файлов следует исключить, добавив проверку состава имени файла.
while ($file = readdir($hdl))

if ( ($file!=".")&&($file!="..")) $a[]=$file;

}
Теперь закроем открытую папку, очистив дескриптор (так необходимо) - функцией closedir (каталог):
closedir($hdl);
Список имен файлов папки, помещенный теперь в массив $а, содержит эти имена в случайном порядке - так их выдает функция readdir. Однако массив можно отсортировать - функциями asort (по алфавиту - прямое) или rsort (по алфавиту - обратное: с z до а). Использование сортировки массива даст возможность включать имена файлов или их содержимое в определенном порядке - достаточно лишь называть их так, чтобы они сортировались нужным образом (скажем, новости удобно именовать датой - файлы с ними могут иметь имена типа 20020901 .php, 20020902.php, тогда при прямой сортировке самые свежие файлы окажутся внизу списка, при обратной -вверху).


rsort($a);
Ну а теперь будем выводить имена по одному с начала массива до конца и использовать их по своему усмотрению. Для этого применим оператор foreach (переменная as массив), который считывает в указанную в его параметрах переменную все элементы массива по очереди, выполняя каждый раз указанный после него в фигурных скобках код, в котором указанная переменная может использоваться:
foreach ($a as $value) {
Комментарий:

Оператор foreach будет работать только вРНР 4.0 и выше. Если вы можете использовать лишь РНРЗ, то вместо него можно использовать немного более громоздкий код - вначале определим размер полученного списка:

$l=sizeof($a);

а затем выполним нижеследующий цикл для каждого элемента массива с помощью цикла for, указав в его параметрах узнанную величину массива:

for ($k = 1; $k < $1; $k++)

Для удобства можно записать значение очередного элемента массива в переменную:

$value=$a[$k]; и получится практически полный аналог оператора for each.
Дальнейший текст сценария зависит от ваших потребностей (и одинаков как для оператора f oreach, так и при использовании цикла for).

Чтобы вывести простой список файлов в папке $dirct, состоящий из гиперссылок на них, можно использовать такую команду, поместив ее в это место сценария:
echo ("<a href = $dirct/$value>$value</axbr>") ;
Чтобы вставить в страницу содержимое всех файлов в папке Sdirct, можно применить команду include:
include ("$dirct/$value");
Данный способ, например, используется при выводе ленты обьяв-лений и новостей на уже упоминавшемся сайте www.harchikov.ru. в корневом каталоге сайта создана папка news, а на его заглавной странице размещен вышеприведенный сценарий (второй вариант -с использованием команды include)/Для помещения на сайт нового объявления администратору достаточно набрать его текст (при необходимости использовав html-разметку, но можно и без нее), поместить этот текст в файл, назвать файл цифровой записью даты создания объявления (для удобства работы и сортировки) и разместить его в папке news на сайте. Никакой редакции каких-либо страниц сайта не требуется. Для удаления объявления с сайта достаточно просто удалить файл с ним из папки news, и впредь выдаваемые посетителям страницы не будут включать в себя его содержимое. Весь процесс нетрудно поручить даже секретарше или полному "чайнику".


Однако для составления списка статей информации только об именах файлов мало. Ведь в таком списке желательно указать хотя бы название статьи и имя ее автора. Чтобы это сделать, можно, например, указывать эти данные в тэгах meta, включаемые в каждый файл со статьей, а узнать содержимое данных тэгов можно с помощью функции get_meta_tags (имя файла).
Комментарий:

функция get__meta_tags (имя файла) создает массив, элементов (В РНР компоненты массива могут иметь не только числовой индекс, но и имена, такой массив называется ассоциативным. Подробнее - ) которого соответствуют названиям мета-тэгов указанного в параметре функции файла (если, конечно, тако-дъге тэги там есть), а значения этих элементов - соответствующим значениям мета-тэгов.
Например, положим, что названия статей будем писать в мета-тэгах zagol, а имена авторов - в мета-тэгах author (т. е. в раздел <head> каждого файла со статьей нужно будет добавить строчки <meta name="zagol" content="3arоловок статьи "><meta name="author" content="ABTop статьи">). Тогда строки сценария, вытаскивающие из файла содержимое этих тэгов и помещающие их на страницу, будут выглядеть так:
$m=get_meta_tags("$dirct/$value");

echo "<a href=$dirct/$value>$m[zagol]</a> &nbsp;$m[author]<br>";
Использование этого способа иллюстрируется в примере на Рисунок 6.1. В папке duel находится файл index.php сданным сценарием, а в папке stats - статьи. В каждом файле со статьей присутствуют мета-тэги zagol и author, в которых указаны названия статей и их авторы. При вызове файла index.php находящийся в нем сценарий пробегает по всем файлам в папке stats, вытаскивает из них мета-тэги и отображает их на странице. Номера в названиях файлов со статьями используются для установки очередности вывода ссылок на них.

Ну и конец сценария:
}

? >

Один скрипт - на все папки



Рисунок 6.2. Один скрипт - на все папки


Таким образом, РНР может снять с web-мастера массу рутинного труда и позволит ему сосредоточиться непосредственно на содержимом сайта, что наверняка послужит только на пользу посетителям.

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



Публикация статей - одной закачкойБез всяких иных изменений



Рисунок 6.1. Публикация статей - одной закачкой. Без всяких иных изменений


При небольшой доработке возможности использования сценария можно серьезно расширить - скажем, генерировать с его помощью списки файлов в любой директории, а не только в указанной. Для этого следует убрать из сценария строку, жестко задавающую имя папки -в приведенном примере $dirct="new";, а значение переменной с именем подлежащей "потрошению" папки с файлами - $dirct -задавать через ссылку для вызова страницы. Если статьи разных номеров журнала помещаются в отдельные папки (например, соответственно называющиеся newsl, news2), то для того чтобы использовать одну и ту же страницу со сценарием для вывода оглавлений различных номеров, нужно указывать имя папки в передаваемой через адресную строку переменной, а впоследствии именно эту переменную использовать в сценарии в качестве имени "потрошимой" папки. Например, ссылки на той странице, откуда происходит переход на страницу со сценарием, могут выглядеть так:

glav.php?dirct=newsl, oglav.php?dirct=news2

и т. д., где oglav.php - страница со сценарием, a $dirct - переменная, в которую записывается имя папки (Рисунок 6.2).



ФОРМА ДЛЯ ПОЛЬЗОВАТЕЛЯ



ФОРМА ДЛЯ ПОЛЬЗОВАТЕЛЯ

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

На странице, с которой должна производиться закачка файлов, следует поставить форму (Рисунок 7.3):

Вот ее код.

Заголовок формы:

<FORM ENCTYPE="multipart/form-data" ACTION "up . php" METHOD=POST>

(Т. е. программа, обрабатывающая загруженный файл, будет помещаться в файле up.php.)



Форма ввода имени файла для загрузки и пароля



Рисунок 7.3. Форма ввода имени файла для загрузки и пароля


Теперь - поле ввода пароля. Его значение при передаче формы запишется в переменную с тем же именем, что и у этого поля (в данном случае - в переменную $pass), а также будет доступно в массиве $HTTP_POST_VARS, в элементе $HTTP_POST_VARS ['pass'] (начиная с РНР версии 4.1 - в элементе $_POST['pass']). Ее вы сможете использовать в сценарии на странице, указанной в параметре action заголовка формы. Если вы укажете в параметре type этого поля значение "text", то вводимые пользователем символы будут отображаться на экране, если "password" - то заместятся звездочками (как на Рисунок 7.3).

Ваш пароль: <INPUT NAME="pass" TYPE="password">

И поле ввода имени файла:

Закачать файл:<INPUT NAME="zak" TYPE="file">

Кнопка начала загрузки:

<INPUT TYPE="submit" VALUE="Закачать">

Собственно, и все... Для загрузки достаточно.

</FORM>



He забудьте назначить папке для файлов нужные права доступа...



Рисунок 7.1. He забудьте назначить папке для файлов нужные права доступа...




Например, вот так



Рисунок 7.2. Например, вот так


В других программах для работы по протоколу FTP права доступа настраиваются аналогично.



ОБЩИЕ СВЕДЕНИЯ



ОБЩИЕ СВЕДЕНИЯ

Чтобы пользователь мог загрузить файл на сервер с web-страницы, на этой странице должна присутствовать форма с параметром заголовка enctype, равном "multipart/form-data", а также со специальным полем типа file (выглядит как поле ввода имени файла с кнопкой "Обзор", нажав на которую, можно отобразить окно выбора файла) и кнопкой submit (см., например, Рисунок 7.3). Как только эта кнопка будет нажата, браузер начнет передавать файл, указанный в поле типа file, на сервер. В заголовке формы также следует указать параметр action, значением которого должно быть имя страницы с обрабатывающим загруженный файл сценарием.

Загрузку файла на сервер умеют осуществлять практически все браузеры (только самые старые модели Microsoft Internet Explorer и Netscape Navigator этого не могут), а воспринять ее могут все web-серверы (кроме CERN и некоторых самых простых), в том числе и самый распространенный - Apache.

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

Странице, указанной в параметре action заголовка формы, передаются несколько переменных ( Если в конфигурационном файле РНР - php.ini - параметр regis-ter_globals установлен в on) содержащих информацию о загруженном файле. Именно на их основе сценарий на ней сможет работать с загруженным файлом. Кроме того, эти же самые переменные помещаются в массив $HTTP_POST_FILES ( Если в конфигурационном файле РНР -php.ini - параметр track_varsустановлен в on), а в РНР версий 4.1 и выше -и в массив SFILES (в отличие от переменных и массива SHTTPPOSTFILES этот массив по умолчанию доступен и во всех функциях, размещенных на странице с программой-обработчиком загруженных файлов).




Вот эти переменные:

1. Переменная, имеющая то же имя, что и поле с типом file в исходной форме. Если оно выглядело как < input name= "uploadf ile" type= " f ile">, то переменная будет иметь имя $uploadfile (и соответственно еще $HTTP_POST_FILES['uploadfile']['tmp_name'], $_FILES [ ' uploadf ile ' ] [ ' tmp_name ' ]). В эту переменную записывается то имя (временное, создающееся автоматически), которое загруженный файл имеет в папке временных файлов. Именно с ним будут работать команды копирования файла.

Если в исходной форме присутствовало несколько полей типа file с разными именами, то для каждого из них создается своя переменная со значением, относящимся к соответствующему файлу.

2. Переменная, имеющая имя "Переменная 1 jiame" - т. е. к имени первой переменной просто приписывается горизонтальная черточка и слово name, например, для вышеуказанного примера ее имя будет выглядеть как $uploadf ile_name (ну и, разумеется, то же самое значение получат элементы вышеупомянутых массивов $HTTP_POST_FILES['uploadfile']['name'], $_FILES ['uploadf ile ' ] ['name ' ]). Ее значением является исходное имя файла в системе отправителя.

3. Переменная, имеющая имя "Переменная 1_size". Ее значение -размер загруженного файла в байтах.

4. Переменная, имеющая имя "Переменная 1_type". Ее значение -тип загруженного файла согласно спецификации MIME (например, "image/gif").

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

Об удалении файла из временной папки после копирования его в нужный каталог можно не думать - это, как уже было сказано, произойдет автоматически.


PHP: ЗАКАЧКА ФАЙЛОВ



PHP: ЗАКАЧКА ФАЙЛОВ

Обычно в создании сайта ведущая роль принадлежит его web-мастеру. Посетителям остается лишь возможность просматривать сайт (для чего он, собственно, и делается) и присылать его администратору свои пожелания по улучшению. Ну и иногда - свои материалы для размещения на сайте.

Однако нередко возникает желание предоставить посетителям больше возможностей - скажем, позволить им помещать свои файлы на сайт. Скажем, вы являетесь администратором сайта "про компьютеры и Интернет" и назначили одного из своих товарищей ведущим того или иного раздела. Так как параметры доступа к аккаунту сайта (логин и пароль) у вас одни (почти все провайдеры хостинга выделяют на это лишь одну пару параметров), то возникает необходимость выбора: либо вы делитесь с товарищем логином и паролем на доступ к аккаунту и тем самым резко снижаете его безопасность (мало ли куда эти данные от товарища могут попасть...), либо берете на себя труд самостоятельно закачивать присылаемые товарищем файлы на сервер. И то, и то весьма и весьма неудобно.

Но есть третий выход из положения. Следует выделить под статьи товарища отдельную папку и позволить ему загружать свои материалы туда и только туда. Как же это сделать?

Прибегнуть к помощи РНР.



ПОДГОТОВКА



ПОДГОТОВКА

Для начала следует создать папку, куда будут помещаться закачиваемые посетителями файлы - скажем, user - в том примере, что будет рассматриваться ниже, и присвоить ей атрибут 772, что означает предоставление посетителям сайта возможность записывать в нее файлы. Для присвоения атрибута достаточно, зайдя с помощью, скажем, CuteFTP на аккаунт, выбрать из контекстного меню этой папки (т. е. из меню правой кнопки мыши) пункт CHMOD (Рисунок 7.1) и указать, что виду пользователей Public разрешается в эту папку что-либо записывать (Рисунок 7.2).



СЦЕНАРИЙ ОБРАБОТКИ



СЦЕНАРИЙ ОБРАБОТКИ

Теперь не менее важная часть - сценарий обработки загруженного файла.

На странице, имя которой указано в параметре action заголовка формы загрузки файла, в любом ее месте следует поместить такой код:

<?php

Если в поле ввода имени файла ничего не было, то выполнение сценария прекращаем (с выводом сообщения пользователю - например, как на Рисунок 7.4), если же нет - то выполняется следующая за данным условием команда elseif:

if ($zak=="none")

{echo ("Вы забыли указать файл...");}



Сообщение пользователю в случае неправильного ввода пароля



Рисунок 7.5. Сообщение пользователю в случае неправильного ввода пароля


Если вы желаете назначить разным пользователям отдельные пароли (чтобы, скажем, иметь возможность запретить загружать файлы лишь одному из них, не затронув интересы остальных), то просто укажите здесь соответствующее условие (может выглядеть так: "elseif ( ($pass!="paroll")&&($pass! = "parol2") )"):

elseif ($pass!="parol")

{ echo ("Ваш пароль неверен!");}

И наконец, само копирование - допустим, в папку user. По его окончании пользователю выдается соответствующее сообщение (Рисунок 7.6).



Сообщение пользователю в случае неуказания имени файла



Рисунок 7.4. Сообщение пользователю в случае неуказания имени файла


Примечание:

Команда elseif используется в операторе if для того, чтобы проводить проверку какого-либо условия в том случае, когда то условие, которое указано в заглавии оператора if, неверно. Она идентична конструкции:

}

else

{

if (выражение) {

} }

и введена в РНР для упрощения синтаксиса программ.

Если введенный пользователем пароль не соответствует тому, что указан в данном сценарии (обратите внимание, что правильный пароль для загрузки файлов указывается именно здесь!), то выполнение сценария прекращаем (с выводом сообщения пользователю - как на Рисунок 7.5), если же нет - то выполняется следующая за данным условием команда elseif.



Сообщение пользователю в случае ошибки копирования



Рисунок 7.7. Сообщение пользователю в случае ошибки копирования


Вот, собственно, и все. Пользователь, зайдя на первую страницу (Рисунок 7.3), должен ввести свой пароль и найти с помощью открывающегося при нажатии на кнопку "Обзор" диалогового окна файл для загрузки. После нажатия кнопки "Загрузить" он увидит одно из трех сообщений - см. Рисунок , ,

Если вместо имен, содержащих информацию о загружаемом файле и передаваемых через форму переменных, использовать имена соответствующих элементов массивов $HTTP_POST_FILES и $HTTP_POST_VARS, то код обработчика будет выглядеть так:

<?php

if ($HTTP_POST_FILES['zak']['name']=="none") {echo ("Вы забыли указать файл...");}

elseif ($HTTP_POST_VARS['pass']!="parol") { echo ("Ваш пароль неверен!");}

elseif

(copy($HTTP_POST_FILES['zak']['tmp_name'], "user/".$HTTP_POST_FILES['zak']['name']))

{echo ("Файл ".$HTTP_POST_FILES['zak1] ['name'] ." размером ".$HTTP_POST_FILES['zak']['size']." байт успешно загружен на сайт.");}

else

echo("Hfe удалось скопировать ".

$HTTP_POST_FILES['zak']['name']);} ?>

Обратите внимание, что при формировании конечного имени файла (в команде сору), а также в строках, выводимых командой echo, писать просто имена элементов массива нельзя - будет выдаваться ошибка! Необходимо использовать оператор конкатенации - точку:

Неправильно:

echo ("Имя файла: $HTTP_POST_FILES['zak']['name']")

Правильно:

echo ("Имя файла:". $HTTP_POST_FILES t'zak'] ['name'])

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

Однако для загрузки нескольких файлов можно использовать и конструкцию с массивом. Для этого достаточно в исходной форме дать полям типа file название с квадратными скобками:

<input name="uploadfile[]" type="file">


<input name="uploadfile[]" type="file">
<input name="uploadfile[]" type="file">

В результате в программу-обработчик будут переданы:

1. Массивы $uploadfile[], $uploadfile_name[], $uploadfile_size[], $uploadfile_type[], содержащие соответственно временные имена загруженных файлов, исходные имена загруженных файлов, размеры загруженных файлов и типы загруженных файлов. Порядок элементов в массивах в точности соответствует порядку полей в исходной форме - так, если имя файла file.zip было введено в первое поле типа file, то относящиеся к этому файлу переменные будут располагаться в элементах перечисленных массивов с индексом 0 (не забывайте - нумерация элементов массивов начинается с нуля!).

Данные массивы будут переданы в обработчик во всех версиях РНР, начиная с 3.0.1, если в файле php.ini ( Настройка этого файла - привилегия администратора web-cepвepa, так что если вы таковым не являетесь, то включить вы ее не сумеете) включена опция regis-ter_globals.

2. Массивы $HTTP_POST_FILES['uploadfile']['tmp_name'][], $HTTP_POST_FILES[luploadfile')['name'][], $HTTP_POST_FILES ['up-loadfile'H'size'][] и $HTTP_POST_FILES['uploadfile']['type'][], содержащие соответственно временные имена загруженных файлов, исходные имена загруженных файлов, размеры загруженных файлов и типы загруженных файлов. Порядок элементов в массивах опять-таки в точности соответствует порядку полей в исходной форме.

Данные массивы будут переданы в обработчик во всех версиях РНР, начиная с 3.0.1, если в файле php.ini включена опция track_vars.

3. Массивы $_FILES['uploadfile']['name'][], $_FILES['uploadfile'] ['tmpjiame'JO, $_FILES['uploadfile']['size'][] u $_FlLES['uploadfile'] I'type'Jl]. Их содержимое аналогично предыдущим. Данные массивы будут переданы в обработчик в версиях РНР, начиная с 4.1.

В данных примерах uploadfde - это всего лишь имя массива, вы, естественно, можете назвать его по-другому.

В РНР 3-й версии с номером подверсии 3.0.17 и выше, а также начиная с версии 4.0.3, в РНР специально для работы с загруженными через форму файлами есть две команды - is_uploaded_file иmove_uploaded_file. При использовании описанного выше способа загрузки файлов существует опасность того, что некий злоумышленник вместо указания в форме реального файла со своего компьютера укажет путь к какому-либо файлу на web-сервере (например, файлу с паролями пользователей), и тем самым сценарий, обрабатывающий загруженный файл, будет работать уже с этим файлом. Ясное дело, такое развитие событий представляется весьма нежелательным. С помощью данных команд можно исключить такую возможность. Первая команда проверяет, был ли тот файл, который указан в ее параметре, загружен через форму загрузки файлов из браузера посетителя, и если да, то возвращает True, в противном случае - False. Вторая же аналогична команде сору, однако, в качсстве#исходного файла для копирования в ней допустимо указывать лишь загруженный от посетителя файл. В противном случае команда не отработает, вернув False (без вывода в документ каких-либо предупреждений, в отличие от ситуации неудачи копирования по каким-либо другим причинам).



Примечание:

Команда is_uploaded__file() no сути дела проверяет, находится ли указанный в ее параметрах файл во временной директории сервера - т. е. той, куда все загружаемые файлы первоначально помещаются. То же самое проверяет иmove_uploaded_file () перед началом копирования.

Так что, как видите, предоставить посетителям возможность загружать файлы на ваш сайт довольно просто. Как и создать простейшую, но довольно эффективную систему ограничения этой возможности по паролю - всего лишь с помощью проверки передаваемой через форму переменной, содержащей пароль; сам же пароль указывается в тексте программы на РНР. Для того, чтобы дать вашему другу возможность вести свою "колонку" на вашем сайте, этого будет достаточно.

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

Однако описанные выше сценарии имеют один весьма существенный недостаток, который, в частности, весьма затрудняет загрузку больших файлов. Обратите внимание, что переход на страницу со сценарием, обрабатывающим загруженный файл и помещающим его в нужную папку, а заодно и проверяющим правильность пароля пользователя, возможен только после полной загрузки файла. Т. е. пользователю, который ввёл неверный пароль, все равно придется ждать окончания бесполезной загрузки его файла на сервер, тратя на это свое время в Сети и трафик. Если загружаемые файлы маленькие, то это еще как-то можно потерпеть, а если они имеют мегабайтные размеры? Тогда ведь вполне можно ждать жалоб от разозленных пользователей, потративших по получасу времени в Интернете на то, чтобы узнать в конце концов, что их пароль неправилен...

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


Сообщение пользователю в случае успешной загрузки



Рисунок 7.6. Сообщение пользователю в случае успешной загрузки


В условии elseif в нижеследующей строчке проверяется, выдает ли команда сору значение True - что должно происходить при успешном копировании. (Если не можете разобраться в синтаксисе -смотрите Описание РНР.)

elseif (copy($zak, "user/$zak_name"))

{echo("Файл $zak_name размером $zak_size байт успешно загружен на сайт.");}

Примечание:

Команда сору выполняет копирование файла из того места, которое указано в ее первом параметре, на то, которое указано во втором. При наличии в месте назначения файла с тем же именем, что и у копируемого, новый файл пишется поверх старого. Команда возвращает True, если копирование проходит удачно, и False, если нет, выводя в последнем случае также сообщение на ту страницу, в сценарии на которой она расположена. (Если последнее нежелательно, то заблокируйте вывод сообщений об ошибке, поставив перед командой знак @.)

В том случае, если по какой-то причине копирование осуществить не удаётся, то об этом выдается сообщение. В принципе это и необязательно - неудача копирования является ошибкой РНР, и об этом информация все равно выводится (Рисунок 7.7), однако все же стоит ясно указать пользователю, из-за чего возникла проблема. К тому же не все смогут понять фразу об ошибке на английском языке.

else

{ echo("He удалось скопировать $zak_name");}

Конец скрипта:

?>