Php 访问其他模型中的CodeIgniter模型

Php 访问其他模型中的CodeIgniter模型,php,codeigniter,Php,Codeigniter,过去,在CodeIgniter模型中,您无法访问其他模型 $this->load->model('bar'); $this->bar->something(); 这仍然有效,还是他们改变了它?我认为通常最好是编写访问模型的库,然后在需要时将库包含在模型中 例如,如果您需要检查某人是否被授权执行某个CRUD操作,那么您可能希望包括您正在使用的任何身份验证库(在大多数情况下,它可能是自动包含的)。您不一定要直接访问该模型——它看起来既脏又不合适 我认为首选的方法是在控制器中

过去,在CodeIgniter模型中,您无法访问其他模型

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

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

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

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

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


无论如何,从本质上讲,我不明白为什么不可能将一个模型包含到另一个模型中。但是,我不认为你能用你展示的语法做到这一点。你得用另一种复杂的方法来做。在任何情况下,IMO,将一个模型直接包含到另一个模型中都是不好的做法

这是可能的,但并不理想,被认为是不好的,更适合于“快速修复”,而不是理想的或纯粹的实现

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对象都可能是个坏主意。尝试重新考虑布局,只需将数据传递到控制器或从控制器传递到模型


我强烈反对“模型”只应使用简单的CRUD操作封装数据库表的观点。如维基百科文章所述:

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

我认为对“模型”的误解部分是由于对“MVC”同样(过度)的炒作,而没有对概念本身有太多的理解。有点像“AJAX”是多么空洞,或者更简单的是,“Web2.0”。不管是好是坏,很多脚本小子都加入了MVC的行列,由于简单的howto和示例场景只告诉您将数据库代码放在“模型”中,因此将该层误用为数据库抽象已经司空见惯。现在,你在互联网上看到的帖子称,在模型中加入任何业务逻辑都是“不纯粹的”、“肮脏的”、“黑客的”。那是错误的。误传

一个简单的例子是考虑外键:即使您只希望您的“模型”是一个数据库模型,如果您希望是“纯粹的”、“正确的”或其他什么,您也确实应该在其中强制执行引用完整性。由于MySQL多年来缺乏真正的外键支持,web应用程序在成长过程中根本不需要担心引用完整性。我想这正符合孩子们的生活方式。无论如何,为了使模型的这种简化视图能够保持外键的有效性,模型必须与其他模型协同工作(或者,特别是如果像CodeIgniter这样的框架不允许您这样做,您必须将查询写入其他表,有时在其他地方复制查询——这是一种糟糕的风格)

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

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


在类似于代码点火器的情况下,我更喜欢两种可能性中的一种:

1) 模型的属性和setter如下:

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);


我认为这些是更干净的可能性。
使用哪种方法取决于需要访问其他模型的方法的数量。如果有一个或两个,最好将其作为方法参数。如果更多-我认为最好有一个类属性和setter。

根据某些条件,您可以优雅地给出一个或另一个模型——如果它们都使用返回的相同类型的数据部分实现相同的接口(这很少有用,但有时可能有用)。

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


简短回答:现在完全支持此功能。如果你愿意的话,可以把货物交出去

正如Phil Sturgeon所说,您可以从模型中加载模型,但如果您在模型构造函数中加载模型,则必须小心依赖关系:如果模型A使用模型B,而模型B使用模型A,则当您尝试加载其中一个时,您将进入一个无限循环。

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

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

库不能在库中使用$this和$this->db,你可以使用上面提到的$this->ci->db是的,但是它很难看。型号更适合升级buddy,2.0.1是当前版本。嘿!问:你是否认为跨负荷模型的坏实践?如果有人遇到这个问题,CODEIGITER现在是第3版。我完全同意这个观点:模型是所有业务逻辑的一个地方,而不仅仅是数据库逻辑。或者做这个$->加载->模型(“前端”);然后调用func
  $this->load->model('X');
  $this->load->model('Y');
  $this->X->doItRightNow($something,$somethingElse,$this->Y);