Расширение класса PHP Smarty Singleton - PullRequest
1 голос
/ 26 июня 2011

Я не совсем уверен, как задать этот вопрос. По сути, я пытаюсь сделать мой объект просмотра синглтоном, вытянутым из объекта 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();

?>

1 Ответ

5 голосов
/ 26 июня 2011

Ваш контроллер не должен расширять 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.Конструктор предварительно настроит экземпляр представления, запроса и ответа.Выполнение определит ActionController для загрузки и запуска.Он загрузит этот контроллер действий и установит представление, а затем определит, какое действие в этом контроллере действий необходимо запустить, и выполнит его.

Если после выполнения контроллера действий ваш фронт-контроллер вызовет View::render(),вернет полную HTML-строку для вывода в браузер и установит ее в качестве содержимого объекта ответа, а также использует метод этого объекта ответа для установки таких вещей, как заголовки и файлы cookie, а что нет.Затем передний контроллер вызовет что-то вроде sendResponse для объекта ответа, который затем отправит заголовки и содержимое в браузер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...