我希望这个社区对设计决策有宝贵的意见。
我正在使用与推进器配对的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;
}
问题是在这种情况下,模型直接与代码点火器库交互,这是否违反了 MVC 范式?
实现此目的的另一种方法是在保存数据时在每个控制器上添加setUserRelatedByUpdateBy和setUserRelatedByUpdateBy,这将是更严格的MVC,但我会在任何地方重复自己完全相同的行。
你会如何处理这个案子?有没有一种正确的方法可以自动实现用户创建/更新行的时间戳行为之类的东西?
谢谢。
我最近调整的经验法则是这样的:
图书馆
库必须尽可能独立。在许多情况下,您甚至可能不会使用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) 我的自定义应用程序/模型/常规的代码.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);
}
}