在PHP MVC应用程序中将数据从Controller传递到View

时间:2013-06-24 15:27:13

标签: php templates variable-assignment

在SO的几乎所有教程或答案中,我都看到了一种将数据从Controller发送到View的常用方法,类View通常看起来与下面的代码类似:

class View
{
    protected $_file;
    protected $_data = array();

    public function __construct($file)
    {
        $this->_file = $file;
    }

    public function set($key, $value)
    {
        $this->_data[$key] = $value;
    }

    public function get($key) 
    {
        return $this->_data[$key];
    }

    public function output()
    {
        if (!file_exists($this->_file))
        {
            throw new Exception("Template " . $this->_file . " doesn't exist.");
        }

        extract($this->_data);
        ob_start();
        include($this->_file);
        $output = ob_get_contents();
        ob_end_clean();
        echo $output;
    }
}

我不明白为什么我需要将数据放入数组然后调用extract($ this-> _data)。 为什么不直接从控制器直接将一些属性放到视图中,如

$this->_view->title = 'hello world';

然后在我的布局或模板文件中,我可以这样做:

echo $this->title;

2 个答案:

答案 0 :(得分:7)

逻辑上有意义的是对视图数据进行分组并将其与内部视图类属性区分开来。

PHP将允许您动态分配属性,以便您可以实例化View类并将视图数据指定为属性。我个人不会推荐这个。如果您想迭代视图数据,或者只是将其转储以进行调试,该怎么办?

将视图数据存储在数组中或包含对象并不意味着您必须使用$this->get('x')来访问它。一个选项是使用PHP5的Property Overloading,它允许您将数据存储为数组,但具有$this->x接口和模板中的数据。

示例:

class View
{
    protected $_data = array();
    ...
    ...

    public function __get($name)
    {
        if (array_key_exists($name, $this->_data)) {
            return $this->_data[$name];
        }
    }
}

如果您尝试访问不存在的属性,将调用__get()方法。所以你现在可以做到:

$view = new View('home.php');
$view->set('title', 'Stackoverflow');

在模板中:

<title><?php echo $this->title; ?></title>

答案 1 :(得分:1)

我的猜测原因可能只是“减少打字”,但这有一些不错的副作用:

  • 帮助编写模板的人不熟悉php,这样他们就不必关心“$this->这意味着什么?”。
  • 如果视图的某些属性应该是该类的私有,并且库编写者不希望将它们公开给模板编写者,那么为变量设置单独的容器也会有所帮助
  • 防止名称与视图自身的属性和模板的变量冲突。
  • 比基于方法的访问方案快得多。可能现在不像创建smarty那样具有相关性(也可以使用php4)。