我对面向对象编程比较陌生。我非常理解这些概念,但实际上,我很难找到有关如何在我的Zend Framework应用程序中最好地使用模型的信息。

具体来说,我有一个不使用数据库表的模型(不扩展任何东西)。它使用getter和setter来访问其受保护的成员。我发现自己正在努力学习如何在视图中最好地展示这个模型。我在视图模板中不需要逻辑,但我发现自己处于以下情况:

在我的控制器中:

$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object;

在我的视图模板中:

<h2><?= $this->object->getName() ?></h2>

我不喜欢在我的视图模板中调用函数,但我不知道更好的方法。我不希望我的模型成员公开,但我基本上想要达到相同的结果:

<h2><?= $this->object->name ?></h2>

我不希望我的控制器完成所有关于模型的所有工作:

$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object;
$this->view->object->name = $object->getName();

在Zend Framework中使用模型的最佳做法是什么?任何人都可以推荐任何可以帮助我理解Zend Framework中的模型/视图困境的教程吗?

有帮助吗?

解决方案

一种可能性是在PHP中使用magic __set和__get方法。我在抽象的Model类中使用它们:

abstract class Model_Abstract
{
    protected 

一种可能性是在PHP中使用magic __set和__get方法。我在抽象的Model类中使用它们:

// Mapped from Model_User::_data->last_name and Model_User::_data->first_name
$this->name 

这使得您可以根据需要为属性指定getter和setter,但这样就不需要为每个属性定义样板函数,只需要对要对其进行某种处理的属性进行定义。在返回值之前。例如,我在许多地方使用该功能将ISO兼容日期(存储在MySQL中)更改为用户更紧凑和可读的格式。

至于控制器中的内容,我建议您查看这篇文章,提供有关在控制器中放置哪些处理的特定反馈。

有些人觉得他们宁愿有一个帮手,可以自动将模型加载到视图中并完全绕过控制器。我个人会说,在Zend Framework和PHP的上下文中,将模型传递到控制器的视图是很有意义的,因为视图中模型的状态经常取决于来自请求的内容(应该绝对应该处理)在控制器中。)

更新:根据评论中的批评,我要指出的一件事是你的数据库访问层和域(或模型)层实际上是两个不同的东西,尽管有Active Record它们混合在一起。我暂时问了这个问题,并收到了一些有用的反馈在这个问题上。无论您决定使用该模型,您都希望为所有域对象提供一致的API,无论模型的数据来自何处。

我认为Saem的答案提供的一个好处是它提供了将属性/函数返回值从一个或多个域对象直接映射到视图对象的功能。从理论上讲,视图中的用法如下所示:

<*>data; // Private Data Members assigned to protected

一种可能性是在PHP中使用magic __set和__get方法。我在抽象的Model类中使用它们:

<*>

这使得您可以根据需要为属性指定getter和setter,但这样就不需要为每个属性定义样板函数,只需要对要对其进行某种处理的属性进行定义。在返回值之前。例如,我在许多地方使用该功能将ISO兼容日期(存储在MySQL中)更改为用户更紧凑和可读的格式。

至于控制器中的内容,我建议您查看这篇文章,提供有关在控制器中放置哪些处理的特定反馈。

有些人觉得他们宁愿有一个帮手,可以自动将模型加载到视图中并完全绕过控制器。我个人会说,在Zend Framework和PHP的上下文中,将模型传递到控制器的视图是很有意义的,因为视图中模型的状态经常取决于来自请求的内容(应该绝对应该处理)在控制器中。)

更新:根据评论中的批评,我要指出的一件事是你的数据库访问层和域(或模型)层实际上是两个不同的东西,尽管有Active Record它们混合在一起。我暂时问了这个问题,并收到了一些有用的反馈在这个问题上。无论您决定使用该模型,您都希望为所有域对象提供一致的API,无论模型的数据来自何处。

我认为Saem的答案提供的一个好处是它提供了将属性/函数返回值从一个或多个域对象直接映射到视图对象的功能。从理论上讲,视图中的用法如下所示:

<*>data public function __construct($data = null) { // Makes it so that I can pass in an associative array as well as // an StdObject. if(!is_object($data)) { $data = (object) $data; } $this->_data = $data; } public function __get($key) { if (method_exists($this, '_get' . ucfirst($key))) { $method = '_get' . ucfirst($key); return $this->$method(); } else { return $this->_data->$key; } } public function __set($key, $val) { if ( method_exists( $this, '_set' . ucfirst($key) ) ) { $method = '_set' . ucfirst($key); return $this->$method($val); } else { $this->_data->$key = $val; return $this->_data->$key; } } } class Model_User extends Model_Abstract { //Example overriding method for the property firstName in the

一种可能性是在PHP中使用magic __set和__get方法。我在抽象的Model类中使用它们:

<*>

这使得您可以根据需要为属性指定getter和setter,但这样就不需要为每个属性定义样板函数,只需要对要对其进行某种处理的属性进行定义。在返回值之前。例如,我在许多地方使用该功能将ISO兼容日期(存储在MySQL中)更改为用户更紧凑和可读的格式。

至于控制器中的内容,我建议您查看这篇文章,提供有关在控制器中放置哪些处理的特定反馈。

有些人觉得他们宁愿有一个帮手,可以自动将模型加载到视图中并完全绕过控制器。我个人会说,在Zend Framework和PHP的上下文中,将模型传递到控制器的视图是很有意义的,因为视图中模型的状态经常取决于来自请求的内容(应该绝对应该处理)在控制器中。)

更新:根据评论中的批评,我要指出的一件事是你的数据库访问层和域(或模型)层实际上是两个不同的东西,尽管有Active Record它们混合在一起。我暂时问了这个问题,并收到了一些有用的反馈在这个问题上。无论您决定使用该模型,您都希望为所有域对象提供一致的API,无论模型的数据来自何处。

我认为Saem的答案提供的一个好处是它提供了将属性/函数返回值从一个或多个域对象直接映射到视图对象的功能。从理论上讲,视图中的用法如下所示:

<*>data collection. protected function _getFirstName() { // Do some special processing and then output the first name. } }

这使得您可以根据需要为属性指定getter和setter,但这样就不需要为每个属性定义样板函数,只需要对要对其进行某种处理的属性进行定义。在返回值之前。例如,我在许多地方使用该功能将ISO兼容日期(存储在MySQL中)更改为用户更紧凑和可读的格式。

至于控制器中的内容,我建议您查看这篇文章,提供有关在控制器中放置哪些处理的特定反馈。

有些人觉得他们宁愿有一个帮手,可以自动将模型加载到视图中并完全绕过控制器。我个人会说,在Zend Framework和PHP的上下文中,将模型传递到控制器的视图是很有意义的,因为视图中模型的状态经常取决于来自请求的内容(应该绝对应该处理)在控制器中。)

更新:根据评论中的批评,我要指出的一件事是你的数据库访问层和域(或模型)层实际上是两个不同的东西,尽管有Active Record它们混合在一起。我暂时问了这个问题,并收到了一些有用的反馈在这个问题上。无论您决定使用该模型,您都希望为所有域对象提供一致的API,无论模型的数据来自何处。

我认为Saem的答案提供的一个好处是它提供了将属性/函数返回值从一个或多个域对象直接映射到视图对象的功能。从理论上讲,视图中的用法如下所示:

<*>

其他提示

如果只有其他开发人员使用模板,我建议只传入模型。以下是MVC上Jeff Atwood帖子的链接了解模型 - 视图 - 控制器

这不是特别针对zend框架,但在我看来,这个问题相当普遍。

似乎你在正确的道路上,而不是在控制器内部将模型硬连接到视图。你宁愿有这样的摘要,如果你要映射一吨模型,或者一遍又一遍地映射同一个模型,那就特别重要了。

一些简单的事情就是编写一堆映射函数,如果你所避免的只是一遍又一遍地映射相同的东西就没问题。

如果你想要一个更通用的解决方案,这也解决了避免编写锅炉板代码,并保持更干燥,我建议创建一个mapper类。

您可以创建一个ViewModelMapper,它可以使用模型或一些模型并将它们映射到视图。

class ViewModelMapper
{
    public function __construct($view)
    {
        //set the properties
    }

    public function addModel($model, $overrideViewProperty = null)
    {
        //add the model to the list of models to map, use the view's property 
        // name to figure out what to map it to? Allow for an override just in case.
    }

    public function getMappedView()
    {
        //take the view, map all the models
    }
}

然后你可以在你的控制器上实现这个,并设置映射,所以控制器仍然控制着映射,但所有控制器映射都集中了所有的样板和编码逻辑,除了极少数例外。

有关模型架构的详细介绍,请阅读这篇文章。它没有具体谈论这个观点,但它绝对值得一读。

我最终在我的模型中添加了 getViewClass()函数。控制器调用此函数来获取它本来无法访问的受保护变量,并且视图不必担心调用任何getter。

//controller
$object = new Object();
$object->setName('Foo Bar');
$this->view->object = $object->getViewClass();

//view template
<h2><?= $this->object->name ?></h2>

我不知道是否有更好的方法可以在Zend Framework中完成工作,但这是一个解决方案。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top