Extending PHP Smarty Singleton Class

狂风中的少年 提交于 2019-12-23 01:44:11

问题


I'm not really sure how to ask this question. Basically I am trying to make my view object a singleton extended from the Smarty object. I then want to be able to extend off of the view object to my controller objects.

The View object will assign my template variables I want available to all my controllers.

I know what I have now has problems, but if someone could point me in the right direction, that would be awesome. I tried to word this the best I could.

<?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:


You controller shouldnt extend the iew.. it should provide data to the view. You also probably wan tto have multiple controllers for different things and at anytime you may need to reqoute the logic to any one of these controllers from another so making the basic controller a singleton isnt a good idea. Instead use a front controller that is a singleton and then action controllers that actually handle the module specific contoller logic.

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;
   }
}

So your index.php would call FrontController::getInstance()->execute(); injecting whatever options for the request life cycle it needs to inject via the options to execute. The constructor would pre configure a view, request, and response instance. Execute will determine the ActionController to load and run. It will load that action controller and set the view, and then determine which action within that action controller needs to be run and execute it.

Your after the action controller is executes your front controller would call View::render() which would return the complete html string to output to the browser and set it as the content on the response object as well as using method on that response object to set things like headers and cookies and what not. The front contoller would then call something like sendResponse on the response object which would then send the headers and the content to the browser.



来源:https://stackoverflow.com/questions/6480563/extending-php-smarty-singleton-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!