9

在几乎所有关于 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;
4

2 回答 2

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>
于 2013-06-24T16:01:42.030 回答
1

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

  • 当编写模板的人不熟悉 php 时会有所帮助,这样他们就不必担心“这$this->意味着什么?”。
  • 当视图的某些属性应该对该类私有并且库编写者不想将它们公开给模板编写者时,为变量设置一个单独的容器也很有帮助
  • 防止名称与视图自身的属性和模板变量发生冲突。
  • 比基于方法的访问方案快得多。现在可能不像创建 smarty 时那样相关(也与 php4 一起使用)。
于 2013-06-24T16:00:02.437 回答