Kohana/PHP-在将记录传递给视图之前向其添加更多信息


Kohana/PHP- adding more information to a record before passing it to the view

场景:我有一个视图,我向它传递了一个kohana记录集对象,视图将遍历每个记录并以适当的格式显示其值。在视图中,我必须用一条消息提醒用户。这个警报只有在满足某些条件时才会被激活,例如,视图必须使用每条记录的date属性执行PHP datediff,并查看它是否是向用户显示警报的最佳时间。

我想的是,而不是视图做计算,我会在控制器内做它。然而,我认为这是一个坏主意,在控制器内部有一个循环,通过每个记录进行迭代,并进行计算,并将记录包装在包装器对象中,以及特定于视图的附加属性。我正在寻找的东西就像一个回调的模型,每次被调用,一个记录被获取。我可以在这里进行计算并返回对象。这种方法在Kohana中可行吗?如果没有,请告诉我符合这个要求的最佳解决方案是什么?

感谢您的时间和关注。

确实,你的建议很好,我一直在用。

我假设你有一个扩展ORM的模型。例如,您可以这样做:

class Model_Example extends ORM {
    protected $_primary_key = 'id';
    protected $_table_name = 'example_table';
    // possibly relations, filters etc.
    function should_message_be_shown() {
        if( !$this->_loaded ) {
            throw new Kohana_Exception('Should only be called on loaded objects');
        }
        if( $this->date_created > ( time() - 3600 ) ) {
            return true;
        }
        return false;
    }
    function get_user_message() {
        if( !$this->_loaded ) {
            throw new Kohana_Exception('Should only be called on loaded objects');
        }
        return 'Hi ' . $this->user_name . '! This is your personal message';
    }
}

方法should_message_be_shown()使用了类变量Model_Example::date_created。这假定您有一个名为date_created的表列,它保存一个UNIX时间戳。因此,在这个特定的例子中,如果记录是在过去一小时内创建的,则返回true。

我增加了一个检查,看看记录是否被实际加载,否则抛出一个异常。

要完成这个示例,您可以在控制器和视图中获取并使用模型,如下所示:

class Controller_Example extends Controller {
    function action_index() {
        $records = ORM::factory('Example')->where('something', '=', true)->find_all();
        $this->response->body(View::factory('example')
                ->set('examples', $records));
    }
}

和视图文件:

<div class="example-list">
    <?php foreach($examples as $example): ?>
        <div class="example-item">
            <h2><?php echo $example->title; ?></h2>
            <?php if($example->should_message_be_shown()): ?>
                <div class="message">
                    <?php echo $example->get_user_message(); ?>
                </div>
            <?php endif; ?>
        </div>
    <?php endforeach; ?>
</div>