扩展PHP Smarty Singleton类

Jus*_*son 1 php class smarty extend

我不确定如何提出这个问题.基本上我试图让我的视图对象从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();
Run Code Online (Sandbox Code Playgroud)

?>

pro*_*son 5

你的控制器不应该扩展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;
   }
}
Run Code Online (Sandbox Code Playgroud)

所以你的index.php会调用FrontController::getInstance()->execute();注入需要通过选项注入的请求生命周期的任何选项execute.构造函数将预先配置视图,请求和响应实例.Execute将确定要加载和运行的ActionController.它将加载该操作控制器并设置视图,然后确定该操作控制器中的哪个操作需要运行并执行它.

您执行操作控制器之后,您的前端控制器将调用View::render()哪个将返回完整的html字符串以输出到浏览器并将其设置为响应对象上的内容以及使用该响应对象上的方法来设置标题和cookie之类的内容什么不是.然后,前端控制器将调用sendResponse响应对象上的内容,然后将标头和内容发送到浏览器.