由用户字段创建和更新,正确处理MVC模式的方法

时间:2013-11-01 08:05:56

标签: php codeigniter propel

我希望这个社区有关设计决策的宝贵意见。

我正在使用与推进配对的CodeIgniter。 我最近不得不在所有现有表中添加updated_by字段,显然我不得不重构所有用法。

用户对象存储在库中,并且(假设所有登录凭据都匹配)可以通过以下方式访问:

$this->auth->getUser(); //Returns a propel collection

我希望自动创建一些东西(有点像时间戳行为)。 有一种简单的方法可以使用类似这样的东西来实现这一点(不要太介意代码,只是在内存中记下来,只是得到了想法):

public function preSave(\PropelPDO $con = null)
{
    $CI =& get_instance();
    $user = $CI->auth->getUser();
    $this->setUserRelatedByUpdatedBy($user)
    if(is_null( $this->getUserRelatedByCreatedBy() ) )
    {
       $this->setUserRelatedByCreatedBy($user);
    }
    return $this;
}

问题在于,在这种情况下,模型直接与codeigniter库交互,这是否违反了MVC范式?

实现这一目标的另一种方法是在我保存数据时在每个控制器上添加setUserRelatedByUpdatedBy和setUserRelatedByUpdatedBy,这将是更严格的MVC,但我会在每个地方用相同的完全相同的行重复自己。

你会如何处理这个案子?有没有一种正确的方法可以自动实现用户创建/更新行的时间戳行为?

非常感谢。

1 个答案:

答案 0 :(得分:2)

我最近改编的Thumb规则是:

图书馆必须尽可能独立。在许多情况下,您甚至可能不使用get_instance()因为库本身应该处理大部分内容 可以将库视为问题的通用解决方案,例如CodeIgniter自己的库,大多数/所有库都是独立的,并且具有特定的用途。

您阅读Form_validation,这正是它的作用。您无需其他库或模型即可使用。通过简单地更改$config值,每个人都可以使用一个好的库。

库应该能够在session库等情况下使用数据库查询;通过使用在配置文件中设置的表名。

模型

模型应该尽可能与数据库查询相关,但更重要的是,为您的项目制作模型。这就是图书馆和模型的不同之处。我曾经偶然发现的典型问题是这个;如果我的模型应该处理数据库调用,那么我在哪里放置我的项目特定的非数据库函数?它们不应该在图书馆中,将它们放在帮助器中是没有意义的,那么我应该把它们放在哪里呢?

我的解决方案是使用通用模型。虽然我的所有其他模型文件都以_model结尾,但我有一个名为general的模型,我用它来加载内部application/models/general的其他模型。如果我运行$this->general->load('utester'),我可以通过$this->general->utester访问新模型。

现在,这可以被质疑等等,但这是我在CodeIgniter工作3年后的结论;一个框架,基本上可以让你做任何你想做的事情。在$this->general内,我知道逻辑与数据库查询没有直接关系。它的功能可能是为form_dropdown()组装数组,它可能是我登录行为的模型,或者不是。

辅助

帮助程序是解析内部视图文件的最佳选择。尽管您可以在视图中使用$this,但最好鼓励在将变量发送到视图之前尽可能在服务器端进行处理,并且应该使用辅助函数解析剩下的内容。如果在视图和控制器中使用了很多函数,你也可以将它作为帮助器。

助手从不需要使用数据库查询。

我已经为这场冲突制定了自己的解决方案,我希望至少能给你一点灵感来提出你自己的解决方案。不要试图在CodeIgniter中找到“最佳”解决方案,选择最有意义的解决方案而不会对它产生不良影响。我眼中的CodeIgniter意味着可以自由地找到自己的个人解决方案。

我不介意听取你对我的方法的看法。一些人可能认为不正确,但让评论家成为你的意见,仅此而已。

1)我的自定义 application / models / general.php

的代码
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

/* Used for Model scalability */
class General extends CI_Model {

    var $loaded     =   array();

    function load($mix)
    {
        $arr_load           =   array();
        $boo_is_array       =   is_array($mix);
        $boo_return_class   =   ! $boo_is_array;
        if ($boo_is_array)
            $arr_load   =   $mix;
        else
            $arr_load[] =   $mix;

        foreach ($arr_load as $int_key => $str_class) {

            $str_lower  =   strtolower($str_class);
            $str_name   =   ucfirst($str_class);

            $str_file   =   APPPATH . "models/general/{$str_lower}.php";

            $boo_success    =   FALSE;
            if (file_exists($str_file))
                if ( ! in_array($str_lower, $this->loaded)) {

                    require_once $str_file;

                    $this->$str_lower   =   new $str_name();
                    $boo_success        =   TRUE;

                }

            if ( ! $boo_success)
                unset($arr_load[$int_key]);

        }

        if ($boo_return_class)
            return $this->$str_lower;

        return (bool) count($arr_load);
    }

}