Большой архив статей, книг, документации по программированию, вебдизайну, компьютерной графике, сетям, операционным системам и многому другому
 
<Добавить в Избранное>    <Сделать стартовой>    <Реклама на сайте>    <Контакты>
  Главная Документация Программы Обои   Экспорт RSS E-Books
 
 

   Интернет технологии -> PHP -> Долой процедурное программирование


Долой процедурное программирование, даешь объектно-ориентированное!

Программисты - народ ленивый. Поэтому, когда дело доходит до работы, они сначала ищут в сети какой-нибудь программный продукт, который в той или иной степени удовлетворяет их потребности в решении поставленной задачи. Если программист пишет что-то на PHP, то одной из первых систем, которые он найдёт, будет PHP Nuke. Поигравшись с ним некоторое время, программист понимает, что вещь, конечно, хорошая, но слишком уж "коряво" написанная, тяжело адаптируемая к задачам, отличных от web-портала, да и перевод на русский язык сделан человеком, имевшем не более трёх очков по великому могучему.

Тем не менее, подход к хранению кода в том виде, как это реализовано в PHP Nuke и описано на большом количестве сайтов, посвящённым PHP, кажется вполне логичным, доступным и приемлемым.

Общая схема этого похода, называемого "модульным", такова: Существует некий главный скрипт, например index.php. Этот скрипт в неком параметре, например, $module, принимает имя модуля, который отдаёт браузеру какую-нибудь страницу. index.php выглядит примерно таким образом:

 <?
 include "config.php";
 if (!$module || !file_exists("modules/$module.inc.php")) {
 $module="default";
 }
 include "modules/$module.inc.php";
?>

Типичный "модуль" при таком построении сайта выглядит так:

<?
 if (!eregi("index.php", $PHP_SELF)) { die ("Access denied"); }
 $page_title="..."; // устанавливаем имя страницы
 include "includes/header.php"; // подключаем дизайн
 // некий <a href="/php">php</a> - код, который генерирует данную страницу
 include "includes/footer.php"; // подключаем остатки дизайна
?>
Вроде бы всё хорошо, однако есть некоторые но:
  1. В каждом модуле нужно делать include заголовка - иначе не сможем изменить <title> и другие тэги в начале страницы.
  2. В каждом модуле необходимо делать
    if (!eregi("index.php", $PHP_SELF)) { die ("Access denied"); }
    - чтобы не вызвали напрямую, миновав различную инициализацию переменных, подключение к СУБД, include общих функций и т.д. в config.php. Хотя, на самом деле, такой запрет делается тремя строчками в .htaccess:
    <files *.php>
    deny from all
    </files>
    
  3. В каждом модуле надо делать include нижней части страницы - по той же причине, что и п.1
  4. При программировании модулей приходиться многократно вызывать одни и те же процедуры: генерацию меню, навигации, баннеров, голосований и т.д. Даже если все эти процедуры будут с красивыми, легкозапоминаемыми именами, с небольшим количеством параметров, будут содержать всё HTML-форматирование внутри себя, то всё равно каждый раз при написании модуля надо будет последовательно написать вызовы всех этих процедур:
    <?
     PageNavigation(module params);
     PageLeftMenu(module params);
     // PHP-код, генерирующий контент
     PageRelatedLinks(module params);
     PageNewsLinks(module params);
     PageVotes(module params);
     PageBanner(module params);
    ?>
    
  5. Другие но, забытые как страшный сон
Таким образом, написание нового модуля начинается с копирования текста старого модуля с последующим исправлением блока, ответственного за контент.

Однако есть способ избавить себя от этого монотонного, длительного и никому не нужного процесса - для этого нужно вспомнить о существовании ООП (объектно-ориентированного программирования) и о том, что PHP очень неплохо это самое ООП поддерживает.

Для начала создадим класс - Web-страницу, в которой опишем все функции, используемые при генерации наших страниц:

class WebPage 
{
// если имя функции совпадает с именем класса, то она считается конструктором
// говоря по-русски, она выполняется при создании объекта
 function WebPage()
 {
 $this->page_title="демо-модуль";
 }
 function PageHeader()
 {
 include "includes/header.inc.php";
 // в этом файле вместо <?=$page_title;?> надо будет написать <?=$this->page_title;?>
 }
 function PageFooter()
 {
 include "includes/footer.inc.php";
 }
 function PageNavigation()
 {
 // Код для навигации
 }
 function PageLeftMenu()
 {
 // Код для меню в левой части страницы
 }
 function PageContent()
 {
 // Код, генерирующий контент
 }
 function PageRelatedLinks()
 {
 // Код, генерирующий ссылки на связанные разделы
 }
 function PageNewsLinks()
 {
 // Код, генерирующий блок новостей
 }
 function PageVotes()
 {
 // Код, генерирующий блок голосований
 }
 function PageBanner()
 {
 // Код, генерирующий баннер
 }
 function Run() 
// ф-я Run последовательно вызывает все необходимые 
// методы класса WebPage для построения страницы
 {
 $this->PageNavigation();
 $this->PageLeftMenu();
 $this->PageContent();
 $this->PageRelatedLinks();
 $this->PageNewsLinks();
 $this->PageVotes();
 $this->PageBanner();
 }
}
?>
Теперь, если нам надо сделать, например, страницу, которая отличается от стандартной только блоком контента, то мы можем определить новый класс, производный от WebPage:
class CoolPage extends WebPage
{
// переопределяем конструктор, чтобы изменить имя модуля
 function CoolPage()
 {
// вызываем конструктор родительского класса - вдруг он что-то полезное делает? ;)
 parent::WebPage();
 $this->page_title="Крутой модуль";
 }
 function PageContent()
 {
 // выводим контент
 }
}
если нам на странице не нужны новости, то мы определяем другой класс:
class CoolPageWithoutNews extends CoolPage
{
// здесь мы не описываем функцию CoolPageWithoutNews 
// в этом случае PHP автоматически вызовет конструктор родительского класса
// соответственно имя нашей страницы будет "крутой модуль"
 function PageNewsLinks()
 {
 // тут пусто, чтобы ссылки на новости не выводились
 }
}
и так далее.

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

Вот пример файла index.php, который может выступать в качестве "главного файла":

<?
 include "config.php";
 include "base_classes.php";
 if ($module && file_exists($file="modules/$module.inc.php")) {
// проверяем, есть ли файл с "телом" класса
 include $file;
 }
 if (!class_exists($module)) {
// проверяем, что класс существует
 $module="WebPage";
 }
 $page=new $module; // создаём объект
 $page->Run(); // запускаем генерацию страницы
}
?>
Примечание: не смотря на то, что весь приведённый выше код ни разу не запускался, вышеуказанная технология, с той разницей, что почти вся информация находится в БД, реально эксплуатируется, например, на моём сайте - dmitry.rsl.ru

Автор: Дмитрий Верещака
Источник: www.dmitry.rsl.ru

 

 
Интересное в сети
 
10 новых программ
CodeLobster PHP Edition 3.7.2
WinToFlash 0.7.0008
Free Video to Flash Converter 4.7.24
Total Commander v7.55
aTunes 2.0.1
Process Explorer v12.04
Backup42 v3.0
Predator 2.0.1
FastStone Image Viewer 4.1
Process Lasso 3.70.4
FastStone Image Viewer 4.0
Xion Audio Player 1.0.125
Notepad GNU v.2.2.8.7.7
K-Lite Codec Pack 5.3.0 Full


Наши сервисы
Рассылка новостей. Подпишитесь на рассылку сейчас и вы всегда будете в курсе последних событий в мире информационных технологий.
Новостные информеры. Поставьте наши информеры к себе и у вас на сайте появится дополнительный постоянно обновляемый раздел.
Добавление статей. Если вы являетесь автором статьи или обзора на тему ИТ присылайте материал нам, мы с удовольствием опубликуем его у себя на сайте.
Реклама на сайте. Размещая рекламу у нас, вы получите новых посетителей, которые могут стать вашими клиентами.
 
Это интересно
 

Copyright © CompDoc.Ru
При цитировании и перепечатке ссылка на www.compdoc.ru обязательна. Карта сайта.
 
Rambler's Top100