一种可能性是在 PHP 中使用神奇的 __set 和 __get 方法。我在我的抽象模型类中使用它们:
abstract class Model_Abstract
{
protected $_data;
// Private Data Members assigned to protected $_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 $_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 的回答提供的一个好处是,它提供了将属性/函数返回值从一个或多个域对象直接映射到视图对象的能力。从理论上讲,视图中的用法如下所示:
// Mapped from Model_User::_data->last_name and Model_User::_data->first_name
$this->name