控制器中加载的Codeigniter模型被模型中加载的模型覆盖

问题描述:

我正在混淆Codeigniter对象范围。

I'm having Codeigniter object scope confusion.

说我在控制器中加载模型:

Say I load a model in a controller:

$this->load->model('A');
$this->A->loadUser(123); // loads user with ID 123
// output of $this->A now shows user 123

$this->load->model('B');
$this->B->examineUser ();
// output of $this->A now shows user 345

class B extends Model
{
    public function examineUser ()
    {
        $this->load->model('A');
        $this->A->loadUser(345); // loads user with ID 345
    }
}

我本以为$ this-> A与$ this-> B-> A会有所不同,但两者没有什么不同。解决此问题的最佳方法是什么?似乎在inspectUser()方法中的-> load-> model('A')无效,因为它已加载到控制器中。然后,对该方法内的loadUser()的调用将覆盖$ this-> A的存储属性。这似乎是一场虫子的等待。如果需要全局模型,则可以使用静态类。我想要的是在某种程度上局限于我所在的模型对象的本地对象。

I would have thought that $this->A would be different from $this->B->A but they are not. What is the best solution to this issue? It appears the ->load->model('A') in the examineUser () method does nothing because it was loaded in the controller. Then the call to loadUser () inside that method overwrites the stored properties of $this->A. This seems like a bugfest waiting to happen. If I needed global models, I would have use static classes. What I wanted was something scoped pretty much locally to the model object I was in.

有没有办法可以做到这一点,但又不能超出CI的常规方法

Is there a way I can accomplish this but not go way outside of CI's normal way of operating?

跟进/相关:
大多数人在哪里放置-> load-> model调用?所有在控制器动作开始时?我认为将它们加载到模型本身(构造或每个方法)会更容易-尽管从依赖项注入的角度看可能不是出色的编程。

Followup/related: Where do most people put there "->load->model" calls? All at the beginning of a controller action? I figured it would be easier -- though perhaps not excellent programming from a dependency injection perspective -- to load them in the model itself (construct or each method).

这是我决定要做的事情,如果您有建议,请发表评论:

Here's what I've decided to do, please comment if you have advice:

我扩展了CI Loader类:

I've extended the CI Loader class:

<?php

class SSR_Loader extends CI_Loader
{
    function __construct()
    {  
        parent::__construct ();
    }  

/**
 * Model Retriever
 *
 * Written by handerson@executiveboard.com to create and return a model instead of putting it into global $this
 *
 * Based on original 2.0.2 CI_Loader::model ()
 *
 */
    function get_model($model)
    {  
        if (empty ($model))
        {  
            return;
        }  

        $name = basename ($model);

        if (!in_array($name, $this->_ci_models, TRUE))
        {  
            $this->model ($model);  
        }  

        $name = ucfirst($name);
        return new $name ();
    }  
}

在我之前,是否有任何CI专家都发现了问题在修改我的代码上花一些时间以接受返回的obj,

Do any CI guru's see a problem with that before I invest time in changing my code a bit to accept the return obj, ala:

// in a controller:
public function test ($user_id=null)
{
    $this->_logged_in_user = $this->load->get_model ('/db/users');
    $this->_viewed_user    = $this->load->get_model ('/db/users');

    $this->_logged_in_user->load($this->session->userdata ('user.id'));
    $this->_viewed_user->load($user_id);
}

我也可以做 private $ _logged_in_user 使其在控制器中可用,但是肯定会迫使它仅限于当前控制器,而不能溢出到其他任何地方,否则我可以执行 $ _ logged_in_user = $ this-> load- > get_model('/ db / users'); 并将其限制为仅当前方法,这可能是我将更常使用的方法。

I could also do private $_logged_in_user to make it available in the controller but positively force it to be limited to just the current controller and not spill anywhere else, or I could just do $_logged_in_user = $this->load->get_model ('/db/users'); and limit it to just the current method, which is probably what I'll do more often.

这似乎是修复此问题的一种非常简单的方法(我说修复 b / c并不是真正的错误,只是一种我认为是不好的主意)。有人看到任何缺陷吗?

This seems like a pretty straightforward way to "fix" this issue (I say "fix" b/c it's not really a bug, just a way of doing things that I think is a bad idea). Anyone see any flaws?