После того, как мы определили, каким должен быть вывод разрабатываемого кода и какие функции он должен выполнять, как реализовать этот код?
Классу наобходимо присвоить логическое имя . Поскольку он представляет страницу, назовем его Page
. Для объявления класса Page
следует ввести:
class Page
{
}
Разрабатываемому классу нужны атрибуты. Элементы, которые, возможно, придется изменять от страницы к странице, мы определим как атрибуты класса. Основное содержимое страницы, которое будет представлено комбинацией HTML-дескрипторов и текста, назовем $content
. Это содержимое можно объявить посредмтвом следующей строки кода внутри определенного класса:
public $content;
Мы можем также определить атрибуты для хранения заголовка страницы. По-видимому, их придется изменять, чтобы посетитель четко знал, какую страницу он просматривает. Вместо использования пустых заголовков, мы зададим заголовок по умолчанию с помощью следующего объявления:
public $title = 'Компания АВС';
Большинство коммерческих веб-страниц включают в себя метадискрипторы, помогающие посковым системам выполнять их индексацию. Чтобы они были полезны, метадискрипторы, по-видимому, должны изменяться от страницы к странице. В этом случае мы также определим значение по умолчанию:
public $keywords = 'компания аbc, автосалон, продажа автомобилей, nissan';
public $description = 'Компания АВС. Автосалон по продажам автомобилей Nissan';
Меню навигации, изображенное ЗДЕСЬ, должно скорее всего оставаться неизменным на всех страницах, чтобы посетители не путались. В то же время, чтобы его можно было легко изменить, мы также должны его сделать атрибутами. Поскольку количество позиций меню может меняться, мы объявим массив и сохраним в нем все ссылки.
Меню горизонтальное:
public $buttons = array (
'Главная' => 'home.php',
'Новости ' => 'news.php ',
'Вакансии ' => 'rabota.php',
'Контакты ' => 'cont.php',
'Карта сайта' => 'mapsite.php'
);
Меню вертикальное:
public $buttons2 = array (
'Каталог автомобилей' => 'catalog.php',
'Сервисный центр' => 'servise.php',
'Запчасти и аксессуары' => 'acses.php',
'Услуги автоцентра' => 'avtoserv.php'
);
Чтобы иметь возможность выполнять те или иные функции, классу также необходимы операции. Их определение можно начать с определений функций доступа, обеспечивающих установку и получения значений атрибутов, которые мы определили. Все функции принимают следующий вид:
public function __set ($name, $value)
{
$this -> $name = $value;
}
Функция __set ()
не содержит проверки на ошибки (для краткости), однако данную возможность при необходимости можно легко добавить. Поскольку маловероятно, что любые из этих значений будут рассматриваться извне класса, мы решили не определять функцию __get ()
.
Основное назначение этого класса заключается в том, чтобы отображать HTML-страницы, а для этого необходима функция. Она получает имя Display ()
и принимает следующий вид:
public function Display ()
{
echo "<html>\n<head>\n";
$this -> DisplayTitle ();
$this -> DisplayKeywords ();
$this -> DisplayDescription ();
$this -> DisplayStyles();
echo "</head>\n<body>\n";
$this ->DisplayHeader ();
$this -> DisplayMenu_h ($this ->buttons);
$this -> DisplayMenu_v();
echo $this -> content;
$this -> DisplayFooter ();
echo "</body>\n</html>\n";
}
Данная функция включает в себя несколько простых операторов echo
для отображения HTML-кода, но в основном состоит из вызовов других функций класса. Как нетрудно догадаться по их именам, эти функции отображают различные части страницы.
Совсем необязательно организовывать функции таким образом. Все эти отдельные функции можно было бы объединить в одну большую функцию. Мы же ввели такое разделение по ряду причин.
Каждая функция должна выполнять определенную задачу. Чем проще задача, тем проще создавать и тестировать функцию. Но не следует заходить слишком далеко в этом направлении — ели вы разобьете программу на очень большое число небольших фрагментов, ее трудно будет читать.
Используя наследование, мы можем выполнять перекрытие операций. Можно заместить одну крупную функцию Display ()
, однако маловероятно, чтобы мы захотели изменить способ отображения всей страницы. Гораздо рациональнее разбить действия по отображению на несколько самостоятельных задач и иметь возможность выполнять перекрытие только тех частей, которые требуется изменить.
Функция Display (отобразить)
вызывает функцию DisplayTitle ()
(отобразить заголовок), DisplayKeywords ()
(отобразить ключевые слова), DisplayDescription ()
(отобразить описание), DisplayStyles ()
(отобразить стили), DisplayHeader ()
(отобразить верхний колонтитул), DisplayMenu_h ()
и $this -> DisplayMenu_v()
(отобразить меню), DisplayFooter ()
(отобразить нижний колонтитул). Это означает, что необходимо определить эти операции. Операции или функции можно записывать в одном логическом порядке, вызывая операцию или функцию еще до того, как в программе встретится фактический код этой операции или функции. Во многих других языках код функции или операции должен быть записан до ее вызова. Большинство используемых в данном случае операций весьма просты и необходимы для отображения некоторого HTML-текста и , возможно, содержимого атрибутов.
В листинге приведенном ниже приводится завершенный класс, который сохранен в файле page.inc
. В таком виде он может быть затребован или включен в другие файлы.
<?php
class Page
{
//атрибуты класса Page
public $content;
public $title = 'Компания АВС';
public $keywords = 'компания аbc, автосалон, продажа автомобилей, nissan';
public $description = 'Компания АВС. Автосалон по продажам автомобилей Nissan';
public $buttons = array ('Главная' => 'home.php',
'Новости ' => 'news.php ',
'Вакансии ' => 'rabota.php',
'Контакты ' => 'cont.php',
'Карта сайта' => 'mapsite.php'
);
public $buttons2 = array ('Каталог автомобилей' => 'catalog.php',
'Сервисный центр' => 'servise.php',
'Запчасти и аксессуары' => 'acses.php',
'Услуги автоцентра' => 'avtoserv.php'
);
//операции класса Page
public function __set ($name, $value)
{
$this -> $name = $value;
}
public function Display ()
{
echo "<html>\n<head>\n";
$this -> DisplayTitle ();
$this -> DisplayKeywords ();
$this -> DisplayDescription ();
$this -> DisplayStyles();
echo "</head>\n<body>\n";
$this ->DisplayHeader ();
$this -> DisplayMenu_h ($this ->buttons);
$this -> DisplayMenu_v($this ->buttons2);
echo $this -> content;
$this -> DisplayFooter ();
echo "</body>\n</html>\n";
}
public function DisplayTitle ()
{
echo '<title> '.$this->title. '</title>';
}
public function DisplayKeywords()
{
echo "<meta name = \"keywords\" content = \"".htmlspecialchars($this->keywords, ENT_QUOTES). "\">";
}
public function DisplayDescription()
{
echo "<meta name = \"description\" content = \"".htmlspecialchars($this->description). "\">";
}
public function DisplayStyles()
{
?>
<link href="abc.css" rel="stylesheet" type="text/css">
<?php
}
public function DisplayHeader ()
{
?>
<div align="center">
<div class="page">
<!--Поиск по сайту -->
<div class="search" align="left">
<form action="search.php" method="get">
<input name="name" type="text"
class="in_input"
value=""
size="28">
<input class="button" type="image" src="images/button.gif" align="absmiddle" >
</form>
</div>
<!--/Поиск по сайту -->
<!--Шапка сайта -->
<div class="header"></div>
<!--/Шапка сайта -->
<?php
}
public function DisplayMenu_h($buttons)
{
echo '<div class="nav_g" align="left">
<ul class="horiz">';
while (list($name,$url) = each($buttons))
{
$this -> DisplayButton ($name, $url, !$this -> IsURLCurrentPage ($url));
}
echo '</ul></div>';
echo '<div class="spacer"></div>';
}
public function IsURLCurrentPage ($url)
{
if (strpos($_SERVER['PHP_SELF'], $url) == false)
{
return false;
}
else
{
return true;
}
}
public function DisplayButton($name, $url)
{
echo "<li class=\"hor\"><a href = '".htmlspecialchars($url)."' class=menu_g >$name</a></li>";
}
public function DisplayMenu_v ($buttons2)
{
?>
<!--Вертикальное меню -->
<div class="nav_v">
<?php
while (list($name,$url) = each($buttons2))
{
$this -> DisplayButton2 ($name, $url, !$this -> IsURLCurrentPage ($url));
}
?>
</div>
<!--/Вертикальное меню -->
<?php
}
public function DisplayButton2($name, $url)
{
echo "<div align=\"left\" class=\"div_v\"><a href = '".htmlspecialchars($url)."' class=menu_v >$name</a></div>";
}
public function DisplayFooter ()
{
?>
<!--нижний колонтитул страницы -->
<div class="spacer"></div>
<div class="copyright">
<div style="margin-top:15px">© Веб-студия Sevidi 2010 год E-mail: [email protected]</div>
</div>
</div>
</div>
<?php
}
}
?>
При просмотре этого листинга обратите внимание, что функции DisplayStyles(), DisplayHeader ()
и DisplayFooter ()
должны отображать большой блок статического HTML-кода без какой либо обработки с помощью РНР. Поэтому внутри функций мы просто указали завершающий РНР-дескриптор (?>
), ввели HTML-код, а затем с помощью открывающего дескриптора (<?php
) снова перешли к РНР.
Примечание. Полностью дистрибутив сайта Компания АВС можно найти ЗДЕСЬ.
В этом классе определены еще две операции. Операция DisplayButton ()
, выводит одиночную ссылку горизонтального меню и обеспечивает единообразный внешний вид страниц.
Операция IsURLCurrentPage ()
определяет, указывает ли связанный с кнопкой URL на текущую страницу. Для этого служит множество технологий. Мы воспользовались строковой функцией strpos ()
, чтобы определить, содержится ли данный URL в одной из переменных, установленных сервером. Оператор strpos($_SERVER['PHP_SELF'], $url)
возвращает число, если строка, хранящаяся в переменной $url
, присутствует внутри суперглобальной переменной $_SERVER['PHP_SELF']
, либо значение false, если это не так.
Чтобы можно было пользоваться классом Page
, файл page.inc
потребуется включить в сценарий и вызвать Display ()
.
Код, показанный в листинге, создает домашнюю страницу сайта компании АВС и обеспечивает вывод, который очень похож на сгенерированный ранее.
<!DOCTYPE HTML>
<?php
require_once ('page.inc');
$homepage = new Page ();
$homepage -> content ='<div class="blok">
<img src="images/maxima.gif" width="95" height="59" alt="Maxima" style="float:left" hspace="2" vspace="2">
<p align="left">Nissan Maxima автомобиль представительского класса</p>
</div>
<div class="blok1">
<img src="images/primera.gif" width="104" height="69" alt="Primera" style="float:left" hspace="2" vspace="2">
<p align="left">Автомобиль бизнес класса. Пользуется большой популярностью у автолюбителей.</p>
</div>
<div class="blok2">
<img src="images/note.gif" width="103" height="63" alt="Note" style="float:left" hspace="2" vspace="2">
<p>Nissan Note открывает семейство автомобилей</p>
</div>
<div class="blok3">
<img src="images/navara.gif" width="103" height="63" alt="Navara" style="float:left" hspace="2" vspace="2">
<p align="left">Nissan Navaga универсал-внедорожник.</p>
</div>
<div class="blok4">
<img src="images/pathfinder.gif" width="98" height="66" alt="Pathfinder" style="float:left" hspace="2" vspace="2">
<p align="left">Nissan Pathfinder представитель семейства внедорожников</p>
</div>
<div class="blok5">
<img src="images/qashqai.gif" width="95" height="66" alt="Qashqai" style="float:left" hspace="2" vspace="2">
<p align="left">Nissan Qashqai представить семейства кроссоверов.</p>
</div>
<div class="blok6">
<h3 style="margin:3px">О компании</h3>
<p>Здесь будет размещена информация о компании АВС</p>
</div>
<div class="blok7">
<h3 style="margin:3px">Новости компании</h3>
<b>07.08.2010 | Новость 4</b>
<br>
Содержимое о новости 4
<div align="right" >
<a href="news.php?id_news=4"
class="rightpanel_lnk">
<img src="../../../images/dot_lnk.gif" hspace="6" border="0" align="absmiddle">подробнее</a>
</div>
<br><b>28.07.2010 | Третья новость</b>
<br>
Новость добавлена для тестирования блока представления
<div align="right" >
<a href="news.php?id_news=3"
class="rightpanel_lnk">
<img src="../../../images/dot_lnk.gif" hspace="6" border="0" align="absmiddle">подробнее</a>
</div>
<br><b>28.07.2010 | Автомобиль X-Treil</b>
<br>
Фотография автомобиля. Тестирование блока новости, в рамках проверки работы скрипта и дизайна страни...
<div align="right" >
<a href="news.php?id_news=2"
class="rightpanel_lnk">
<img src="../../../images/dot_lnk.gif" hspace="6" border="0" align="absmiddle">подробнее</a>
</div>
<br><div align="left">
<a href="news.php"
class="rightpanel_lnk">все новости</a><br>
</div><br> </div>';
$homepage -> Display();
?>
В окне веб-браузера это будет выглядеть ТАК.
Код, приведенный выше, выполняет следующие действия:
- Использует опрератор
require_once
для включения содержимого файлаpage.inc
, который содержит определение класса Page. - Создает экземпляр класса
Page
. Этому экземпляру назначается имя$homepage
. - Устанавливает содержимое, включающее некотоый текст и HTML-дескрипторы, которые должны быть на странице. При этом неявно вызывается __set().
- Вызывает опреацию
Display ()
внутри объекта$homepage
, которая обеспечивает отображение страницы в окне браузера посетителя.
Как видно из листинга, для генерации новых страниц с использованием класса Page требуется выполнить совсем незначительный объем работы. Такое использование класса означает, что допустимо лишь незначительное отличие страниц друг от друга.
Если нужно,чтобы в некоторых разделах сайта использовался вариант стандартной страницы, можно просто скопировать page.inc в новый файл page2.inc
и внести в него некоторые изменения. Это значит, что при каждом обновлении или исправлении в файле page.inc
нельзя забывать внести эти же изменения и в файл page2.inc
.
Более рациональный подход предусматривает использование механизма наследования для создания нового класса, который наследует большую часть своих фуннкциональных возможностей от класса Page
, ноиперекрывает те части, которые должны отличаться.
Применительно к сайту Компания АВС требуется, чтобы страница Услуги автоцентра содержала другую навигационную панель.
Создадим сценарий который решает эту задачу путем создания нового класса ServicesPage
, унаследованного от класса Page
. В этом классе мы определим новый массив buttons3
. Поскольку мы хотим, чтобы этот класс в основном сохранил поведение родительского класса, мы перекроем только ту часть, которая должна измениться, а именно — операцию Display()
.
<!DOCTYPE HTML>
<?php
require_once ('page.inc');
class ServicesPage extends Page
{
private $buttons3 = array('Техобслуживание ' => 'service1.php',
'Ремонт' => 'service2.php',
'Установка' => 'service3.php',
'Другие услуги ' => 'service4.php'
);
function Display ()
{
echo "<html>\n<head>\n";
$this -> DisplayTitle ();
$this -> DisplayKeywords ();
$this -> DisplayDescription ();
$this -> DisplayStyles();
echo "</head>\n<body>\n";
$this ->DisplayHeader ();
$this -> DisplayMenu_h ($this ->buttons);
$this -> DisplayMenu_v($this ->buttons3);
echo $this -> content;
$this -> DisplayFooter ();
echo "</body>\n</html>\n";
}
}
$services = new ServicesPage ();
$services -> content ='<div class="blok8">
<h2 align="center">Услуги автоцентра</h2>
<p>В этом разделе будет размещена инфомация об услугах автоцентра </p><img src="images/phpsite95.gif" width="347" height="231" alt="Автосалон" style="float:left; margin-right:10px" hspace="3" vspace="2" >
<div ><p><a href="/phpsite/webpage/sitetest/avtoserv.php?id_catalog=5"
class="menu_g">Услуги автоцентра</a></p></div></div>';
$services -> Display();
?>
В окне веб-браузера это будет выглядеть ТАК.
Перекрытая операция Display ()
очень похожа на операцию в родительском классе, но содержит одну дополнительную строку:
$this -> DisplayMenu_v($this ->buttons3);
которая вызывает операцию DisplayMenu_v
и создает новую панель меню.
За пределами определения класса мы создаем экземпляр класса ServicesPage
, устанавливаем значения, которые отличаются от значений по умолчанию, и вызываем операцию Display ()
.
Мы создали и получили новый вариант стандартной страницы. При этом нам пришлось создавать код только для отличающихся частей страниц.
Создание страниц при помощи РНР-классов обладает очевидным преимуществами. Учитывая, что класс выполняет большую часть действий, для создания новой страницы приходится выполнять меньший объем работы. Мы можем обновлять сразу все страницы, для этого достаточно обновить класс. Пользуясь механизмом наследования, из оригинала можно получить различные версии класса, сохраняя при этом указанные выше преимущества.
Однако, как часто бывает в жизни, за упомянутые преимущества приходится платить.
Для создания страниц из сценария требуется больше процессорных операций, чем для простой загрузки статической HTML-страницы с диска и пересылки ее в браузер. Для сайта с высоким трафиком это имеет большое значение, поскольку нам придется либо использовать статические HTML-страницы, либо по возможности кэшировать вывод сценариев, где только возможно, чтобы тем самым уменьшить нагрузку на сервер.
Комментарии(0)
Для добавления комментариев надо войти в систему и авторизоватьсяКомментирование статей доступно только для зарегистрированных пользователей:Зарегистрироваться