Шаги к MVC или как правильно (или неправильно) сделать проект

wrapper

Guest
Автор оригинала: Alexandre

wrapper
чисто технический вопрос:
каким образом осуществляется
и как часто?

над остальным я просто буду думать
Ну это не самая елегантная часть :)
Все идет в 2-а этапа:
1) Парсится xml (делаю это DOMXML функциями)
И создается обьект ProjectDescriptor который содержит всю информацию по приложению для данной роли (anonymous, user, admin...)
PHP:
class ConfigParser {					
	/**
	 *
	 * @access public
	 * @return ProjectDescriptor 
	 **/
	function getProjectDescriptor($role) {		
		$dom = @domxml_open_file($GLOBALS['PCOF']['CONFIGURATION_FILE_PATH']);
		if($dom == null) {
			Engine::raiseFatalError(new Error("Unable to parse configuration file"));
		}		
		$project = $dom->document_element();						
		$projectDescriptor = new ProjectDescriptor();
		
		//Get roles
		$rolesNodeList = $project->child_nodes();				
		foreach($rolesNodeList as $rolesNode) {			
			if(($rolesNode->node_type() == XML_ELEMENT_NODE) && ($rolesNode->node_name() == "roles")) {								
				if($role == null) {
					$role = $GLOBALS['PCOF']['PCOF_DEFAULT_ROLE'];
				}
				if($role == null) {
					Engine::raiseFatalError(new Error("Bad configuration. Unable to resolve role.<br>No role was found in session and no role was defined as default in configuration"));	
				}									
				$roleNodeList = $rolesNode->child_nodes();
				foreach($roleNodeList as $roleNode) {
					if(($roleNode->node_type() == XML_ELEMENT_NODE) && ($roleNode->node_name() == "role")) {
						if($roleNode->get_attribute("id") == $role) {
							$roleDescriptor = new RoleDescriptor();
							$roleDescriptor->id = $roleNode->get_attribute("id");														
							$projectDescriptor->role = $roleDescriptor;	
						}						    											
					}		
				}		
			}		
		}
                //...
          }
2) Потом этот $projectDescriptor передается классу который на основании его создает файл (anonymous.php, user.php, admin.php...)

Код:
class ConfigCompiler {
	/**
	 *
	 * @access public
	 * @return void
	 * @param role - string, role of user (defined in configuration.xml). f.e.: anonymous, user, admin
	 * Creates php file	 
	 **/
	function compile($projectDescriptor) {
		$role = $projectDescriptor->role->id;				
		$handle = @fopen ($GLOBALS['PCOF']['CONFIG_COMPILER_DIR'].$role.".php", "w");							
		fwrite($handle, "<? \r\n");		
		fwrite($handle, "global \$projectDescriptor; \r\n");
		fwrite($handle, "\$projectDescriptor = new ProjectDescriptor();\r\n");
		
		fwrite($handle, "\r\n//Init Role\r\n");
		fwrite($handle, "\$roleDescriptor = new RoleDescriptor();\r\n");
		fwrite($handle, "\$roleDescriptor->id=\"".$projectDescriptor->role->id."\";\r\n");
                //...
                ConfigCompiler::saveCompilationTime();
        }
        //...
}
>Как часто?
Каждый раз сверяю timestamp-ы редактирования конфига и последней компиляции. При желании можно эту проверку убрать и запускать компиляцию ручками. Тогда и тормозной DOMXML на хостинге не нужен, можно просто закачивать их туда скомпиленные.

2 Ямерт
Velocity поддерживает много логических конструкций так что уж если кто захочет то запихнет туда что угодно :)
Разве что в базу может не полезешь
 

Alexandre

PHPПенсионер
Velocity поддерживает много логических конструкций так что уж если кто захочет то запихнет туда что угодно :)
а можно Velocity использовать в качестве шаблонного движка, или smarty вполне достаточно?
 

Alexandre

PHPПенсионер
VeloCity на java написан
я и сам знаю, что на ява,
вопрос о другом: Кто -нибудь пробовал использовать VeloCity в качестве шаблонного движка на пхп ???

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

_RVK_

Новичок
Вот объясните мне, может я чего не понимаю в концепции MVC, но ИМХО, smarty и xslt не в полной мере соответствуют этой модели, так как должны обеспечивать View но берут на себя часть функций Контроллера.
 

Screjet

Новичок
Originally posted by Diesel
Вот объясните мне, может я чего не понимаю в концепции MVC, но ИМХО, smarty и xslt не в полной мере соответствуют этой модели, так как должны обеспечивать View но берут на себя часть функций Контроллера.
Смотря с какой стороны посмотреть:
С одной стороны = соответствуют. В шаблотронах происходит разбор документа, формирование вывода, а потом только вывод.

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

зы. Был крайне удивлен, когда скачал какуюто версию PHPInside! и там как раз был именно такой пример для smarty.
 

_RVK_

Новичок
Странная противоречивость, все трубят о достоинствах модели MVC и при этом сами же её нарушают, зачем то запихивая логику в представление. Пэтому, мне кажется не стоит упоминать смарти, в темах где идет речь о MVC, или сразу делать соответствующую оговорку.
 

Alexandre

PHPПенсионер
Diesel
smarty и xslt не в полной мере соответствуют этой модели, так как должны обеспечивать View
думаю - они должны обеспечивать только View (и функциональность View )
только я не понимаю, в какой степени они
берут на себя часть функций Контроллера
можно этот момент поподробнее??
 

_RVK_

Новичок
Alexandre
Дело в том, что в smarty и xslt шаблонах присутствует логика, даже такие операторы как if и for (их аналоги). А логика, это прирагатива Контроллера. Мало того, шаблоны смарти вообще компилируются, и после этого могут обходится вообще (ну или почти) без Контроллера, точнее контроллер становится как бы составной частью View. Я не хочу опсуждать достоинства и недостатки конкретных движков (в конце концов никто не заставляет использовать логические операторы и функции в шаблонах smarty или xslt) ,но мне интересно, как это вяжется с концепцией MVC.
 

Макс

Старожил PHPClub
Diesel
логика оформления и бизнес-логика - это разные вещи.
В данном случае бизнес-логикой занимаеться Модель, а логикой оформления вывода - xslt
 

_RVK_

Новичок
Макс
А вывести такую-то строчку n раз, если то то равно тому то, это не бизнес-логика? Получается в функции контоллера входит лишь установить нужные теги в нужные значения. Мне гажется логика оформления должна быть линейна, шаблон(View) определяет что, за чем и как вывести, и лишь Controller решает что, когда и почему.
 

Макс

Старожил PHPClub
Diesel
А вывести такую-то строчку n раз, если то то равно тому то, это не бизнес-логика?
слишком абстрактный пример. В общем случае - нет. Хотя можно придумать и исключения
 

_RVK_

Новичок
Макс
Тогда если идти от обратного, то при использовании обычных шаблонизаторов, мы заставляем Контроллер заниматься несвойственной ему работой, а именно оформительством. Хотя конечно функции htmlspecialchars, nl2br, uppercase и т.п. можно отнести к офрмительству, но в остальном же это не так...
 

Макс

Старожил PHPClub
обычные шаблонизаторы, это типа pear::html::template::sigma , pear::html::template::IT, phplib::template и тому подобные ?

шаблонизатор - не есть Представление.
Можно написать например класс ProductView который будет получать данные и заниматься оформлением. Посмотри примеры на phppatterns.com
 

_RVK_

Новичок
шаблонизатор - не есть Представление
А я такого не говорил, Представление есть шабон, в идеале. Вообще, зыбкая эта грань. Можно сказать что шаблонизатор это часть Контроллера, тогда все вроде встает на свои места...
 

Alexandre

PHPПенсионер
Уровень представления - рассуждения на тему шаблонизатор

Какой должен быть уровень Представления Данных, объем и состав бизнесс логики на уровне представления?

Возмем слой М-V
M- отвечает за источники данных, связанных с отображением т.е. связь с БД
V - за визуализацию этих данных. В нашем случае это шаблонизатор.

Есть два подхода к шаблонизации:
- простая шаблонизация (аналог класса FastTemplate )
- шаблонизация c встроенной логикой (смарти или XSLT)

Пример первый: отобразить страницу с таблицей из БД:

M- тянет из БД данные таблицы и представляет их ввиде массива.

В первом случае:
V - вызывает подшаблон 1, с отображением табличной части, и генерит выходной HTML-код табличной части.
Далее - вызывает подшаблон 2, с отображением общей части, и генерит выходной HTML-код общей части
!! итого отработало 2 файла шаблонов

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

Пример 2:
Надо отобразить карточку товара, притом отображается выпадающий список категории товаров.

M- тянет из БД данные таблицы:
- товар = id
- все категории тоаров
и представляет их ввиде двух массивов.

В первом случае:
V - вызывает подшаблон 1, с отображением информации о товаре, и генерит выходной HTML-код.

вызывает подшаблон 2, с формированием элемента ComboBox категории товаров, и генерит выходной HTML-код (<SELECT>.... </SELECT>).
Ситуация усложняется с установкой начального значения ComboBox ( <Option selected> )

Далее - вызывает подшаблон 3, с отображением общей части, и генерит выходной HTML-код общей части
!! итого отработало 3 файла шаблонов

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

Недостатки первого метода:
- растет кол-во файлов пропорционально "элементов управления"

Недостатки второго метода:
- растет сложность логики шаблона

Информация для размышления
:confused: Какой должен использоваться тип шаблонов в MVC

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

P.S. Под "источником данных" понимается результат выполнения запроса к БД, в соответствии с логикой Модели

-~{}~ 03.09.04 11:01:

но мне интересно, как это вяжется с концепцией MVC.
Diesel
мне тоже это интерестно знать, по этому см. топик выше

-~{}~ 03.09.04 11:05:

Представление есть шабон, в идеале. Вообще, зыбкая эта грань. Можно сказать что шаблонизатор это часть Контроллера, тогда все вроде встает на свои места...
разделение на слои M-V чисто условное. Как сам разделишь, так и будет.

Главное чтоб :
а) все работало
в) работало правильно
с) работало быстро и без тормазов
d) и всем этим былоб удобно пользоваться
 

Макс

Старожил PHPClub
Diesel
Представление есть шабон, в идеале.
я уже предлагал посмотреть примеры на пхппаттернс. ИМХО эти простые примеры наиболее четко показывают идеологию MVC. Там View - это отдельный класс (ProductView), причем там в View тоже есть логика - но это логика оформления, он манипулирует лишь данными, которые через контроллер ему предоставила Модель.

Примеры там очень простые и если следовать им то прийдется на каждый объект web-сайта (Пользователь, Статья, Категория, Голосование и т.д.) делать свой View, то есть будет много View-классов, поскольку у каждого объекта своя логика оформления. Как по мне - это неудобно при написании больших (по объему) скриптов.
Так вот. XSLT или Smarty, в силу того, что имеют встроенные возможности, обеспечивающие логику оформления упрощают написание View-классов. Может написать один View-класс, который просто от контроллера будет получать весь сгенерированный XML + список XSLT-файлов, которые нужно подключить. View подключит все стили, наложит на XML и выдаст результат
 

hash

Guest
нифига не понял, но читал с ужасно умным видом....
мне кажется, что ООП, независимо в чем его реализовывать, достаточно удобная вещь, и я жутко рад, что когда открыл книжку по php, увидел там раздел об ООП...

З.Ы. не обращайте внимания
 

regi

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

www:
/news
/about
/articles
/other
site.php
page.php
config.php
index.php

ну это примерно.
site.php - содержит класс site со всеми основными методами(регистрация юзеров, логин, добавление, удаление продуктов из корзины, и т.п. вещи)
config.php - содержит несколько переменных типа $title='название';
$nav='начало навигации'; по идее это можно разместить и в файле site.php
page.php - содержит весь дизайн сайта, что то типа этого:

PHP:
$page='<html>
<head><title>'.$title.'</title>
<body>'.nav.'<br>'.$main.'</body>
</html>';
а index.php - содержит вот что:
PHP:
include("config.php");
include("site.php");
//Проводим необходимые действия по выборке данных и затем:
$title.='Название главной страницы';
$nav.='Главная';
$main='Что мы хотим увидеть на главной странице';
//подключаем дизайн
include("page.php");
echo $page;
Все остальные разделы построены таким же образом.
Один из плюсов - достаточно понятные url адреса.

Хорош ли такой метод построения среднего сайта?

ps: естественно можно еще подключить класс для работы с бд и что-нибудь еще :)
 

Alexandre

PHPПенсионер
естественно можно еще подключить класс для работы с бд и что-нибудь еще
regi Когда придумаешь, как подключить класс БД, то дай знать. Для меня это самая больная проблема: Как подключить класс Модели.
 
Сверху