Я не совсем уверен, как задать этот вопрос. В основном я пытаюсь сделать объект моего объекта Singleton расширенным от объекта Smarty. Затем я хочу, чтобы можно было отделить объект вида от объектов контроллера.
Объект View назначит переменные шаблона, которые я хочу использовать для всех моих контроллеров.
Я знаю, что у меня сейчас есть проблемы, но если кто-то может указать мне в правильном направлении, это будет потрясающе. Я попытался сказать это как можно лучше.
<?php defined('SITE_ROOT') ? null : define('SITE_ROOT', $_SERVER['DOCUMENT_ROOT'].'/mvcsandbox'); require_once('Smarty/Smarty.class.php'); class View extends Smarty { public static $instance=NULL; public static function getInstance(){ if ( self::$instance === null ){ self::$instance = new self(); } return self::$instance; } public function __construct() { $this->template_dir = SITE_ROOT.'/Library/tmp/'; $this->compile_dir = SITE_ROOT.'/Library/tmp/'; $this->config_dir = SITE_ROOT.'/Library/tmp/'; $this->cache_dir = SITE_ROOT.'/Library/tmp/'; $this->assign("var1", "This is from the view class"); } public static function output() { self::display('test.tpl'); } } class Controller1 extends View { public function init() { $this->assign("var2", "This is from the Controller1 class"); } } class Controller1_index extends Controller1 { public function init() { $this->assign("var3", "This is from the Controller1_index class"); } } //$view = View::getInstance(); $controller1 = Controller1::getInstance(); $controller1_index = Controller1_index::getInstance(); $controller1->init(); //$controller1_index->init(); $controller1->output();
?>
Вы, контроллер, не должны расширять iew .. он должен предоставлять данные для представления. Вероятно, вы также можете иметь несколько контроллеров для разных вещей, и в любое время вам может потребоваться переназначить логику для любого из этих контроллеров от другого, поэтому основной контроллер – это идеальная идея. Вместо этого используйте фронт-контроллер, который является синглтоном, а затем контроллерами действий, которые фактически обрабатывают специфическую для модуля логику контоллера.
class Controller { // put any shared logic between all controllers here } class FrontController extends Controller { protected $request; // a model representing and http request protected $response; // a model representing a http response protected $view; // the view instance protected static $instance; // the FrontController instance protected function __construct(); public static function getInstance(); public function getRequest(); public function getResponse(); public function getView(); public function execute($args); } class View { protecect $engine; public function __Construct($options) { // $options could contain overrides for smarty config $options = array_merge(array( 'template_dir' = SITE_ROOT.'/Library/tmp/', 'compile_dir' = SITE_ROOT.'/Library/tmp/', 'config_dir' = SITE_ROOT.'/Library/tmp/', 'cache_dir' = SITE_ROOT.'/Library/tmp/', ), $options); $this->engine = new Smarty(); foreach($options as $name => $value){ $this->engine->$name = $value; } } public function getEngine(){ return $this->engine; } // proxy method calls and accessors not directly defined on // the View to the Smarty instance public function __get($key) { return $this->engine->$key; } public function __set($key, $value){ $this->engine->$key = $value; return $this; } public function __call($method, $args){ if(is_callable(array($this->engine, $method)){ return call_user_func_array(array($this->engine, $method)); } } public function render(){ // render the entire smarty instance } } class ActionController extends Controller { protected $view; public function init(); public function setRequest(); public function getRequest(); public function getResponse(); public function execute($request, $response); public function getView(); public function __get($key){ return $this->view->$key; } public function __set($key, $value){ $this->view->$key = $value; } }
Таким образом, ваш index.php вызовет FrontController::getInstance()->execute();
вводя любые варианты жизненного цикла запроса, которые ему нужно вводить с помощью опций для execute
. Конструктор предварительно настроил бы экземпляр вида, запроса и ответа. Execute будет определять ActionController для загрузки и запуска. Он загрузит этот контроллер действий и установит представление, а затем определит, какое действие в этом контроллере действия необходимо запустить и выполнить.
После выполнения контроллера действия ваш фронт-контроллер будет вызывать View::render()
который возвращает всю строку html для вывода в браузер и устанавливает ее как содержимое объекта ответа, а также использует метод для этого объекта ответа установить такие вещи, как заголовки и файлы cookie, а что нет. Передний контролер затем вызывал что-то вроде sendResponse
для объекта ответа, который затем отправлял заголовки и содержимое в браузер.