【问题标题】:DRY MVC view/controller separationDRY MVC 视图/控制器分离
【发布时间】:2012-06-14 11:55:20
【问题描述】:

我有一个自定义的 MVC PHP 框架,它有一个路由器类,它调用一个控制器,它使用一个模型,然后控制器呈现视图等。

我的问题是,从技术上讲,我无法从语义上弄清楚如何允许变量在控制器和视图之间传递。我可以做一个快速而肮脏的修复,但我想要的是控制器:

class IndexController extends Controller{
    var $name = "John"; // instance variable
}

并以此为鉴:

<p> <?=$name?> </p>

我的问题是这样的:

  1. 如何创建一个 Controller->render() 函数或类似的函数,以允许视图从控制器访问实例变量?并且,
  2. 我怎样才能做到这一点而不做像$data['view']['name'] = "John"; 这样的笨拙的事情,或者在默认情况下为我制作的任何新控制器编写十行代码。我想这样做,以使其尽可能干燥。

谢谢。

编辑:FabioCosta 的解决方案

我不确定我是否理解,到目前为止,我的基本控制器是这样的:

<?php
    class Controller{
        public function __get($key){
            if(isset($this->$$key)) return $this->$$key;
        }
    }
?>

我的基本视图类如下所示:

<?php
    class View{
         public $controller;
         public function render(){
         $this->controller = $this;
    }
?>

我像这样从路由器初始化:

<?php
    $controller = new IndexController();
    $view = new IndexView();
    $view->render();
?>

但是,这不起作用,我知道我做错了什么。

【问题讨论】:

  • 你使用的是什么版本的 PHP?
  • 你的 MVC 使用什么框架?
  • 我认为我正在使用最新的 PHP 5.3。 @Gavin“我有一个自定义的 MVC PHP 框架......”,就像我自己做的那样。
  • 为什么你在 5.3 的时候还在使用var 关键字?
  • @Gavin ,请不要使用 CodeIgniter 作为正确 MVC 的示例 .. 甚至一般的正确开发实践

标签: php model-view-controller frameworks dry


【解决方案1】:

为什么不传递实例化视图的控制器并使用 __get 魔术方法?

像这样:

  public function __get($key){

      if(isset($this->$key)) return $this->$key;
  }

这是一个工作示例 View.php:

class View{
   protected $_controller;
   public function __construct(Controller $controller){
        $this->_controller=$controller;
   }
   public function render(){
        echo '<h1>Hello '.$this->_controller->name.'</h1>';
   }
}

控制器.php

class Controller{
    protected $name='fabio';
    protected $_myView;

    public function __get($key){

        if(isset($this->$key)) return $this->$key;
   }
    public function __construct(){
        $this->_myView=new View($this);
    }

    public function indexAction(){
        $this->_myView->render();
    }
}

还有路由器:

$c=new Controller();
$c->indexAction();

【讨论】:

  • 看起来不错,这将如何在我的代码中工作?例如,如何传递控制器?
  • 也许在 render 方法中,在控制器中你放了 get magic 方法。在渲染函数中你把 $view->setController($this)
  • 另外,这是在控制器还是视图类中?谢谢。
  • 控制器类php.net/manual/en/language.oop5.overloading.php#object.get,在视图类中设置setController方法
  • 现在您有一个示例,其中控制器依赖于类Viewname,并且控制器正在泄漏封装。那里的 OOP 真的很糟糕。
【解决方案2】:
  1. 控制器不应负责渲染输出。这是view 实例应该做的事情。渲染应该发生在控制器之外。

  2. 视图应从model layer 请求数据。然后,根据它收到的信息,选择正确的template,分配数据并渲染这个模板(或者在某些情况下——模板组)。

另外,路由器不应该初始化控制器和视图。控制器应该只负责处理请求。

【讨论】:

  • 我真的很喜欢视图从视图中请求数据的想法。那么视图会是一个层吗?它将负责用数据填充各种模板。我想这就是我之前所说的控制器。如果这是真的,那么你在这里所说的关于路由器和控制器的内容让我感到困惑。控制器是做什么的?它是从哪里调用的?路由器只是在控制器之前调用吗?
  • 路由机制是一个单独的问题。它接受用户的输入,并转换为可供应用程序其余部分使用的形式(我通常以Request 实例结束)。控制器仅接受该请求并将数据分发到适当的服务和当前视图。控制器基本上是:“这是我们收到的数据 - 处理它”。
  • 这是否意味着控制器在传递请求后不再出现在图片中?你有例子吗?
猜你喜欢
  • 2014-06-21
  • 1970-01-01
  • 2011-12-12
  • 2012-10-23
  • 1970-01-01
  • 2013-11-17
  • 2018-12-27
  • 2012-04-15
  • 2011-08-11
相关资源
最近更新 更多