在其他模型中访问 CodeIgniter 模型

Posted

技术标签:

【中文标题】在其他模型中访问 CodeIgniter 模型【英文标题】:Accessing CodeIgniter Models in Other Models 【发布时间】:2010-10-26 17:39:45 【问题描述】:

过去,在 CodeIgniter 模型中,您无法访问另一个模型。

$this->load->model('bar');
$this->bar->something();

这仍然有效,还是他们改变了它?

【问题讨论】:

【参考方案1】:

对于一个简单的问题,这些答案很长。

简答:现在完全支持。如果您愿意,请交叉加载!

【讨论】:

哥们该升级了,2.0.1是当前版本。 嘿!问题:您认为交叉加载模型是不好的做法吗? 如果有人偶然发现这个问题,CodeIgniter 现在是第 3 版。【参考方案2】:

我非常不同意“模型”应该只用简单的 CRUD 操作封装数据库表的观点。如***文章中所述:

http://en.wikipedia.org/wiki/Model-view-controller#As_a_design_pattern

...该应用程序层的目的不仅仅是充当单个数据库表抽象。想一想“控制器”这个词的含义——它应该更多地充当导演,而不是作为整个应用程序本身。 “模型”业务逻辑的地方。事实上,大多数大型应用程序的大部分业务逻辑都保存在数据库本身中(以触发器、存储过程、外键等形式)。

我认为对“模型”的误解部分是由于对“MVC”的相同(过度)炒作造成的,而没有对概念本身有太多理解。有点像“AJAX”是多么空洞,或者更简单,“Web 2.0”。不管是好是坏,很多脚本小子都跳上了 MVC 的马车,而且由于简单的操作方法和示例场景除了告诉您将数据库代码放入“模型”之外并没有做更多的事情,因此滥用该层作为只有一个数据库抽象已经变得司空见惯。现在,您在互联网上阅读帖子称其为“不纯”、“肮脏”、“骇人听闻”,将任何业务逻辑放入模型中。那是错误的。误导。

简单的例子是考虑外键:即使你只希望你的“模型”是一个数据库模型,如果你想成为“纯”、“正确”或其他你,你真的应该在其中强制执行参照完整性。由于 mysql 多年来缺乏真正的外键支持,Web 应用程序在没有任何人担心引用完整性的情况下成长起来。我猜这符合剧本小子的生活方式。无论如何,即使是模型的这种简化视图也能够保持外键有效性,模型必须与其他模型一起工作(或者,特别是如果像 CodeIgniter 这样的框架不允许您这样做,您必须向其他模型编写查询表,有时会在其他地方重复查询 - 这是不好的风格)。

因此,我认为这是 CodeIgniter 的一个缺点。我知道这可能不是一个容易解决的问题,但这肯定是一个令人失望的疏忽。

所以我所做的是将上面的示例代码抽象为一个帮助程序,这样我现在就有了一个与正常 $this->load->model() 功能几乎相同的函数。在这里(将其放入自动加载的助手中,您可以在任何模型中使用它):


   /**
    *
    * Allow models to use other models
    *
    * This is a substitute for the inability to load models
    * inside of other models in CodeIgniter.  Call it like
    * this:
    *
    * $salaries = model_load_model('salary');
    * ...
    * $salary = $salaries->get_salary($employee_id);
    *
    * @param string $model_name The name of the model that is to be loaded
    *
    * @return object The requested model object
    *
    */
   function model_load_model($model_name)
   
      $CI =& get_instance();
      $CI->load->model($model_name);
      return $CI->$model_name;
   

【讨论】:

我完全同意这个观点:模型是所有业务逻辑的地方,而不仅仅是数据库逻辑。 或者这样做 $this->load->model('frontend');然后像 $this->frontend->myFunction() 这样调用函数【参考方案3】:

这是可能的,但不是理想的,被认为是不好的,而且“快速修复”比理想或纯粹的实现更重要。

class Location extends Model
      public function get($ID)
                // Get main CI object handle and load model
                $CI =& get_instance();
                $CI->load->model('LocationType');
                // Call new model functions using handle to main CI object
                $CI->LocationType->setID($result->LocationTypeID);
                $CI->LocationType->setTitle($result->TypeTitle);
                $this->_locationType = $CI->LocationType;
                //Other Stuff
    

任何时候你像这样使用主要的 CI 对象都可能是个坏主意。尝试重新考虑您的布局,将数据传入/传出控制器到模型。

http://codeigniter.com/forums/viewthread/69833/

【讨论】:

【参考方案4】:

您可以像 Phil Sturgeon 所说的那样从模型中加载模型,但是如果在模型构造函数中加载模型,则必须注意依赖关系:如果模型 A 使用模型 B,而模型 B 使用模型 A,那么当您尝试加载时一种或另一种,你会进入一个无限循环。

【讨论】:

【参考方案5】:

在 Code Igniter 中的这种情况下,我更喜欢以下两种可能性之一: 1) 具有这样的模型属性和设置器:

class X extends Model 
  var $Y_model;
  public function setY($Y) 
    $this->Y_model = $Y;
  

  public function doItRightNow($a,$b) 
    $list = $this->Y_model->getSomeList($a,$b);
    // ...
  
  // ...

然后在其他方法之前使用这个setter来给其他模型的一个实例,以便它可以被方法使用。

$this->load->model('X');
$this->load->model('Y');
$this->X->setY($this->Y);
$this->X->doItRightNow($something,$somethingElse);

2) 在方法中有一个参数,我将通过该参数从控制器中提供另一个模型实例。

class X extends Model 
  public function doItRightNow($a,$b,$Y_model) 
    $list = $Y_model->getSomeList($a,$b);
    // ...
  
  // ...

并像这样使用它:

  $this->load->model('X');
  $this->load->model('Y');
  $this->X->doItRightNow($something,$somethingElse,$this->Y);

我认为这些是更干净的可能性。 使用哪种方式取决于需要访问其他模型的方法数量。如果有一个或两个,最好将其作为方法参数提供。如果更多 - 我认为最好有一个类属性和设置器。 您可以优雅地根据某些条件给出一个模型或另一个模型 - 如果它们都部分实现相同的接口并返回相同类型的数据(它很少有用,但有时可能)。

【讨论】:

【参考方案6】:

我认为访问模型然后在需要时将库包含在模型中的编写库通常会更好。

例如,如果您需要检查某人是否被授权通过某个 CRUD 操作,您可能希望包含您正在使用的任何身份验证库(在大多数情况下它可能会自动包含)。你不一定想直接访问模型——它看起来很脏而且不合适。

我认为首选方法是在控制器中执行您需要执行的操作,并将结果从一个模型的方法(如果需要)传递给您的另一个模型的方法。

无论如何,我不明白为什么不能将一个模型本身包含到另一个模型中。不过,我认为您无法使用所显示的语法来做到这一点。您将不得不以其他复杂的方式进行操作。无论如何,IMO,将模型直接包含到另一个模型中是不好的做法。

【讨论】:

库不能使用 $this 和 $this->db 在库中,您将使用 $this->ci->db 如上所述 是的,但它很难看。模型更好【参考方案7】:

在 CI 2.0 中,您可以直接从另一个模型调用一个模型。

【讨论】:

【参考方案8】:

最好创建一个辅助函数,而不是从另一个模型中调用该函数,这样它可以一次在 2 个模型中使用,并且可以重复使用代码。

【讨论】:

以上是关于在其他模型中访问 CodeIgniter 模型的主要内容,如果未能解决你的问题,请参考以下文章

Codeigniter - 从模型访问控制器数据

在非 Codeigniter 类中加载和使用 Codeigniter 模型

CodeIgniter:将值形成模型函数

CodeIgniter:在每个库中加载模型或将模型从控制器内“传递”到库中

我可以对多个表使用单个 CodeIgniter 模型吗?

可以在 CodeIgniter 的模型中调用另一个模型中的方法吗?