扩展 PHP Smarty Singleton 类

发布于 2024-11-16 22:57:42 字数 1553 浏览 0 评论 0原文

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

?>

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();

?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

救赎№ 2024-11-23 22:57:42

您的控制器不应该扩展视图。它应该向视图提供数据。您可能还希望拥有多个控制器来处理不同的事情,并且在任何时候您可能需要将逻辑从另一个控制器重新路由到其中任何一个控制器,因此使基本控制器成为单例并不是一个好主意。相反,使用单例的前端控制器,然后使用实际处理模块特定控制器逻辑的操作控制器。

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 的内容,然后将标头和内容发送到浏览器。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文