На главную Назад
Добро пожаловать, уважаемый посетитель!

 

ГЛАВА 9

РНР идинамическое создание страниц

Многиечитатели в любой книге о компьютерахпролистывают все, что не представляетнепосредственного интереса, и переходят ктому, что они действительно хотятзнать. Лично я поступаюименно так. Впрочем, в этом нет ничегострашного - редко встречаются техническиекниги, которые необходимо читать от коркидо корки. А может, вы именно так и поступили- пропустили восемь начальных глав ивзялись за эту главу, потому что у нее былосамое интересное название? Да и комузахочется тратить время на подробности,когда на работе <горит> очередной проект?

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

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

Простыессылки

По ссылкампользователь может переходить как наобычные страницы HTML, так и на страницы,содержащие код РНР:

<а href = "date.php"><Viewtoday's date</a>

Еслищелкнуть на ссылке, в браузере будетзагружена страница с именем date.php. Просто, неправда ли? Развивая приведенный пример,можно воспользоваться переменной дляпостроения динамической ссылки:

<?

$link = "date.php";

print "<а href= \"$link\">View today's date</a> <br>\n"

?>

Вероятно, увас возник вопрос - почему в коде ссылкиперед кавычками (") ставится обратнаякосая черта (\)? Дело в том, что кавычки в РНРявляются специальными символами ииспользуются в качестве ограничителейстрок. Следовательно, кавычки-литералы встроках должны экранироваться.

Еслинеобходимость экранировать кавычки васраздражает, просто включите режим magic_quotes_gpcв файле php.ini. В результате все апострофы,кавычки, обратные косые черты и нуль-символы.в тексте автоматически экранируются!

Разовьемприведенный пример. Для быстрого выводасписка ссылок в браузере можновоспользоваться массивом:

<?

// Создатьмассив разделов

$contents - array("tutorials","articles", "scripts", "contact");

// Перебратьи последовательно вывести каждый элементмассива

for ($i = 0; $i < sizeof($contents;$i++)

print " &#149;<a href = \"".$contents[$i].".php\">".$contents[$i]."</a><br>\n";

// &#149; -специальное обозначение точки-маркера endfor;

?>

Файловыекомпоненты (шаблоны)

Мы подошли кодной из моих любимых возможностей РНР.Шаблоном (применительно к web-программированию)называется часть web-документа, которую высобираетесь использовать в несколькихстраницах. Шаблоны, как и функции РНР,избавляют вас от лишнего копирования/вставкифрагментов содержания страницы ипрограммного кода. С увеличением масштабовсайта значение шаблонов возрастает,поскольку они позволяют легко и быстропроводить модификации на уровне целогосайта. В этом разделе будут описанынекоторые возможности, которые открываютсяпри использовании простейших шаблонов.

Как правило,общие фрагменты содержания/кода (то естьшаблоны) сохраняются в отдельных файлах.При построении web-документа вы просто <включаете>эти файлы в соответствующие места страницы.В РНР для этого существуют две функции: include() и require( ).

include( ) и require()

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

опытомпрограммирования на других языках (например,С, C++ или Java), хорошо знакомы с концепциейбиблиотек функций и их использованием впрограммах для расширения функциональныхвозможностей.

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

Функции

В РНРсуществуют четыре функции для включенияфайлов в сценарии РНР:

  • include( );
  • include_once( );
  • require( );
  • require_once( ).

Несмотря насходство имен, эти функции решают разныезадачи.

include( )

Функция include() включает содержимое файла в сценарий.Синтаксис функции include( ):

include (file файл]

У функцииinclude( ) есть одна интересная особенность -ее можно выполнять условно. Например, есливызов функции включен в блок команды if. тофайл включается в программу лишь в томслучае, если условие i f истинно. Еслифункция includeO используется в условнойкоманде, то она должна бытьзаключена в фигурные скобки или вальтернативные ограничители. Сравнитеразличия в синтаксисе листингов 9.1 и 9.2.

Листинг9.1. Неправильноеиспользование include( )

if (some_conditional)

include('text91a.txt'); else

include('text91b.txt');

Листинг9.2. Правильноеиспользование include( )

if (some_conditional) :

include('text91a.txt');

else :

include('text91b.txt');

endif;

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

print "this is aninvalid include file";

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

<?

print "this is aninvalid include file";

?>

include_once( )

Функцияinclude_once( ) делает то же, что и include( ), за однимисключением: прежде чем включать файл впрограмму, она проверяет, не был ли онвключен ранее. Если файл уже был включен,вызов include_once( ) игнорируется, а если нет -происходит стандартное включение файла. Вовсем остальном include_once( ) ничем не отличаетсяот include( ). Синтаксис функции include_once( ):

include_once (file файл)

require ( )

В целомфункция require( ) похожа на include( ) - она тожевключает шаблон в тот файл, в которомнаходится вызов require( ). Синтаксис функцииrequire( ):

require (file файл)

Тем не менее,между функциями require( ) и include( ) существуетодно важное различие. Файл, определяемыйпараметром require( ), включается в сценарийнезависимо от местонахождения require( ) всценарии. Например, при вызове requi ге( ) вблоке if при ложном условии файл все равнобудет включен в сценарий!

Во многихситуациях бывает удобно создать файл спеременными и другой информацией, котораяиспользуется в масштабах сайта, и затемподключать его по мере необходимости. Хотяимя этого файла выбирается произвольно, яобычно называю его init.tpl (сокращение от ).В листинге 9.3 показано, как выглядит оченьпростой файл init.tpl. В листинге 9.4 содержимоеinit.tpl включается в сценарий командой require( ).

Листинг9.3. Примеринициализационного файла <?

<?

$site_title = "РНРRecipes";

$contact_email = "wjgilmore@hotmail.com";

$contact_name = "WJ Gilmore";

?>

Листинг9.4. Использованиефайла init.tpl

<? require ('init.tpl');?>

<html>

<head>

<title><?print $site_title; ?></title>

</head>

<body>

<? print "Welcometo $site_title. For questions, contact <a href =

\"mai1to:$contact_email\">$contact_name</a>."; ?>

</body>

</html>

ПередачаURL при вызове require( ) допускается лишь привключенном режиме (этот режимвключен по умолчанию).

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

require_once( )

Функцияrequire_once( ) гарантирует, что файл будетвключаться в сценарий всего один раз. Послевызова requi rе_оnсе( ) все дальнейшие попыткивключения того же файла игнорируются.Синтаксис функции requiге_оnсе( ):

require_once(file файл)

Если несчитать дополнительной проверки, востальном эта функция аналогична

require( ).

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

Построениекомпонентов

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

Заголовок

Заголовочныйфайл (вроде приведенного в листинге 9.5)присутствует практически в каждом из моихweb-сайтов с поддержкой РНР. В этом файлесодержится

информация,действующая на уровне всего сайта, -например, заголовок, контактные данные инекоторые компоненты кода HTML-страницы.

Листинг9.5. Примерфайла заголовка

<?

// Файл: header.tpl

// Назначение:заголовочный файл для сайта PhpRecipes .

// Дата: 22августа 2000 г.

$site_name = "PHPRecipes";

$site_email= "wjgnmore@hotrnail.com";

$site_path = "http://localhost/phprecipes";

?>

<html>

<head>

<title> <?print $site_name; ?> </title>

</head>

<body bgcolor="#7b8079"text="#ffffff" link="fe7d387" alink="#e7d387"vlink="#e7f0e4">

<table width="95%" cellpadding="0"cellspacing="0" border="1">

<tr>

<td valign = "top">

PHPRecipes

</td>

<td valign = "top"align="right">

<?

// Вывеститекущую дату и время

print date ("F d,h:i a");

?>

</td>

</tr>

</table>

Довольночасто доступ к включаемым файлам со стороныпосетителей ограничивается, особенно еслиэти файлы содержат конфиденциальнуюинформацию (например, пароли). В Apache можнозапретить просмотр некоторых файловредактированием файлов http.conf или htaccess.Следующий пример показывает, как запретитьпросмотр всех файлов с расширением .tpl:

<Files "*.tpl">

Order allow,deny

Allow from 127.0.0.1

Deny from all

</Files>

РНРи проблемы безопасности сайтов подробноописаны в главе 16.

Колонтитул

Колонтитулом(footer) обычно называется информация,расположенная в нижней части страниц сайта,- контактные данные, ссылки и информация обавторских правах. Эту информацию можноразместить в отдельном файле и включать вкачестве шаблона так же, как это делается сзаголовком. Допустим, c наступлениемнового года вам потребовалось изменитьинформацию об авторских правах ипривести ее к виду . Есть двапути: потратить канун Рождества налихорадочное редактирование сотенстатических страниц или воспользоватьсяшаблоном наподобие приведенного в листинге9.6. Одно простое изменение - и вы можетевозвращаться к праздничным хлопотам.

Листинг 9.6.Пример файла колонтитула (footer.tpl)

<table width="95%"cellspacing="0" cellpadding="0" border="1">

<tr><td valign="top"align="middle">

Copyright &copy;2000 PHPRecipes. All rights reserved.<br>

<a href = "mailto:<?=$site_email;?>">contact</a>| 

<a href = "<?=$site_path:?>/

privacy.php">yourprivacy</a>

</td></tr>

</table>

</body>

</html>

Обратитевнимание на использование глобальнойпеременной $site_email в файле колонтитула.Значение этой переменной действует вмасштабах всей страницы, а мы предполагаем,что файлы header.tpl и footer.tpl будут включены водну итоговую страницу. Также обратитевнимание на присутствие пути $site_path в ссылкеPrivacy (Конфиденциальность). Я всегда включаюв шаблоны полные пути ко всем ссылкам -если бы URL ссылки состоял из одного имениprivacy.php, то файл колонтитула был бы жесткопривязан к конкретному каталогу.

Основнаячасть

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

Листинг9.7.Примеросновной части страницы (index_body.tpl)

<table width="95%"cellspacing="0" cellpadding="0" border="1">

<tr>

<td valign="top"width="25%>

<a href ="<?=$site_path;?>/tutorials.php">tutorials</a> 

<br>

<a href ="<?=$site_path:?>/articles.php">articles</a> 

<br>

<a href ="<?=$site_path;?>/scripts.php">scripts</a> 

<br>

<a href ="<?=$site_path;?>/contact.php">contact</a> 

<br>

</td>

<td valign="top"width="75%">

Welcome to PHPRecipes.the starting place for PHP scripts, tutorials, 

and information about gourmetcooking!

</td>

</tr>

</table>

Все вместе:заголовок, колонтитул и основная часть

Вероятно,мое настроение лучше всего выражаетсяфразой полковника <Ганнибала> Смита (ДжорджПеппард) из знаменитого сериала <Команда А>:<Люблю, когда все становится на свои места>.Я испытываю нечто подобное, когдаразрозненные шаблоны объединяются иобразуют полный web-документ. Комбинируя трисекции документа: header.tpl, index_body.tpl и footer.tpl, -можно быстро построить простейшую страницувроде той, что приведена в листинге 9.8.

Листинг9.8. Построениестраницы index.php включением несколькихфайлов

<?

// Файл: index.php

// Назначение:домашняя страница PHPRecipes

// Дата: 23августа 2000 г.

// Вывестизаголовок

include ("header.tpl");

// Вывестиосновную часть

include ("index_body.tpl");

// Вывестиколонтитул

include ("footer.tpl");

?>

Ну как? Трипростые команды - и перед вами готоваястраница. Текст итоговой страницы приведенв листинге 9.9.

Листинг9.9. СтраницаHTML, построенная в листинге 9.8 (index.php)

<html>

<head>

<title>PHPRecipes </title>

</head>

<body bgcolor="#7b8079"text="#ffffff" link="#e7d387" alink="#e7d387"vlink="#e7f0e4">

<table width ="95%" cellpadding="0" cellspacing="0" border="1">

<tr>

<td valign = "top">

PHP Recipes

</td>

<td valign = "top"align="right">

August 23, 03:17 pm

</td>

</tr>

</table><tablewidth="95%" cellspacing="0" cellpadd1ng="0" border="1">

<tr>

<td valign="top"width="25%">

<a href = "htfp://localriost/phprecipes/tutorials.php">tutorials

</a> <br>

<a href = "http://localhost/phprecipes/articles.php">articles

</a> <br>

<a href = "http://localhost/phprecipes/scripts.php">scripts</a>

<br>

<a href = "http://localhost/phprecipes/contact.php">contact</a>

<br>

</td>

<td valign="top"width="75%">

Welcome to PHPRecipes,the starting place for PHP scripts, tutorials, 

and gourmet cooking tips andrecipes!

</td>

</tr>

</table><table width="95%"cellspacing="0" cellpadding="0" border="1">

<tr><td valign="top"align="middle">

Copyright &copy;2000 PHPRecipes. All rights reserved.<br>

<a href = "mailto:wj@hotmail.com">contact</a> | 

<a href = "http://localhost/phprecipes/privacy.php">yourprivacy</a>

</td></tr>

</table>

</body>

</html>

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

Рис. 9.1. Внешнийвид страницы, построенной в листинге 9.8

Оптимизацияшаблонов

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

Листинг9.10. Оптимизированныйшаблон сайта (site_init.tpl)

<?

// Файл:site_init.tpl

// Назначение:инициализационный файл PhpRecipes

// Дата: 22августа 2000 г.

$site_name = "PHPRecipes";

$site_email = "wjgilmore@hotmail.com";

$site_path = "http://localhost/phprecipes/";

function show_header($site_name){

<html>

<head>

<title> <?print $site_name: ?> </title>

</tiead>

<body bgcolor="#7b8079"text="#ffffff" link>"#e7d387" alink="#e7d387"vlink="#e7f0e4">

This is the header

<hr>

function show footer ()

?>

<hr>

This Is the footer

</body>

</html>

<?

}

?>

Листинг9.11. Применениеинициализационного файла

<?

// Включитьинициализационный файл

include("site_init.tpl");

// Вывестизаголовок

show header ($site_name);

?>

// Содержимоеосновной части This is some body information

<?

// Вывестиколонтитул Show_footer( );

?>

Проект:генератор страниц

Хотя вбольшинстве созданных мною web-сайтовосновное содержимое страниц формировалосьна основании информации, прочитанной избазы данных, всегда найдется несколькостраниц, которые практически не изменяются.В частности, на них могут выводитьсясведения о команде разработчиков,контактные данные, реклама и т. д. Я обычнохраню эту <статическую> информацию вотдельной папке и использую сценарий РНРдля ее загрузки при поступлении запроса.Конечно, у вас возникает вопрос - если этостатическая информация, для чего нуженсценарий РНР? Почему бы не загружатьобычные страницы HTML? Преимущество РНРзаключается в том, что вы можетеиспользовать шаблоны и вставлятьстатические фрагменты по меренеобходимости.

Ссылки длязагрузки различных статических файловстроятся динамически. В обобщенной формессылка выглядит так:

<а href ="<?=$site_path:?>/static.php?content=$content">Static PageName</a>

Начнем ссоздания статических страниц. Для простотыя ограничусь тремя страницами, содержащимиинформацию о сайте (листинг 9.12), рекламу (листинг9.13) и контактные данные (листинг 9.14).

Листинг9.12. Информацияо сайте (about.html)

<h3>AboutPHPRecipes</h3>

What programmer doesn'tmix all night programming with gourmet cookies. Here at PHPRecipes. hardly anight goes by without one of our coders mixing a little bit of HTML with a tastyplate of Portobello Mushrooms or even Fondue. So we decided to bring you thebest of what we love most: PHP and food!

<p>

That's right, readers.Tutorials, scripts, souffles and more. <i>0nly</i> at PHPRecipes.

Листинг9.13. Рекламнаяинформация (advert_info.html)

<h3>AdvertisingInformation</h3>

Regardless of whetherthey come to learn the latest PHP techniques or for brushing up on how

to bake chicken, youcan bet our readers are decision makers. They are the Industry

professionals who makedecisions about what their company purchases.

For advertisinginformation, contact <a href - "mailto:ads@phprecipes.com

">ads@phprecipes.com</a>.

Листинг9.14. Контактныеданные (contact.html)

<h3>Contact Us</h3>

Have a coding tip? <br>

Know the perfect topping for candied yams?<br>

Let us know! Contact the team at <a href= "mailto:theteam@phprecipes.com">team@phprecipes.com</a>.

Переходим кпостроению страницы static.php, которая выводитзапрашиваемую статическую информацию. Вэтот файл (см. листинг 9.15) включаютсякомпоненты страниц нашего сайта иинициализационный файл site_init.tpl.

Листинг9.15. Общийвывод статических страниц (static.php)

<?

// Файл: static.php

// Назначение:отображение запрашиваемых статическихстраниц.

// ВНИМАНИЕ: предполагается, чтофайл "site_init.tpl" и все

// статическиефайлы находятся в том же каталоге.

// Загрузитьфункции и переменные include("site_init.tpl"):

// Вывестизаголовок show_header($site_name);

// Вывестизапрашиваемое содержание include("$content.html"):

// Вывестиколонтитул show footer( );

?>

Теперь всеготово к построению основного сценария.Просто включите в страницу

следующиессылки:

<а href = "static.php?content=about">StaticPage Name</a></br>

<a href = "static.php?content=advert_info">AdvertisingInformation</a></br>

<a href = "static.php?content=about">ContactUs</a></br>

Еслищелкнуть на любой из этих ссылок, в браузерезагружается соответствующая статическаястраница, внедренная в static.php!

Итоги

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

  • обработка URL;
  • построениединамического содержания;
  • включение ипостроение базовых шаблонов.

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

Следующаяглава посвящена использованию РНР всочетании с формами HTML, заметно повышающимистепень интерактивности вашего сайта. Апотом - взаимодействие с базами данных! Вампредстоит узнать много интересного.