【问题标题】:Extending PHP Smarty Singleton Class扩展 PHP Smarty Singleton 类
【发布时间】:2011-09-22 18:14:39
【问题描述】:

我不确定如何问这个问题。基本上,我试图使我的视图对象成为从 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();

?>

【问题讨论】:

  • 我认为你的意思是“单身”:D 虽然这个比喻很惊人。
  • 是的,“Simpleton”引用我觉得不错,不过我真诚地建议您放弃 Smarty 并尝试在模板中使用 PHP's native capabilities

标签: php class smarty extend


【解决方案1】:

您的控制器不应该扩展 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()-&gt;execute(); 注入它需要通过选项注入到 execute 的请求生命周期的任何选项。构造函数会预先配置视图、请求和响应实例。 Execute 将确定要加载和运行的 ActionController。它将加载该动作控制器并设置视图,然后确定该动作控制器中的哪个动作需要运行并执行。

在执行动作控制器后,您的前端控制器将调用View::render(),它将返回完整的 html 字符串以输出到浏览器并将其设置为响应对象上的内容以及使用该响应对象上的方法设置诸如标题和cookie之类的东西等等。然后前端控制器会在响应对象上调用类似sendResponse 的东西,然后将标题和内容发送到浏览器。

【讨论】:

  • 非常感谢!我确实改变了一点。使它更像是我最初的想法和你展示给我的东西之间的融合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-27
  • 2012-07-31
  • 2013-02-06
  • 2017-01-09
相关资源
最近更新 更多