用户
 找回密码
 入住 CI 中国社区
搜索
查看: 13814|回复: 7
收起左侧

[模型] 在一个Model中调用另一个Model的问题

[复制链接]
发表于 2010-11-16 00:27:00 | 显示全部楼层 |阅读模式
公司的框架是基于CI开发的。用着很舒服。这几天自已搞个东西用的CI,发现很多问题,CI真的很不方便,问题很多。

CI模型中不对载入模型
比如在game_model.php这个模型中不能使用
      $this->load->model('test');
这样的方式载入模型,其实是载入成功了。但是不能通过
      $this->test->function();
这样调用。报错提示对像不存在。
可以通过
$CI =& get_instance();
$CI->test->function();这样的方式调用

解决方法

在system/libraries/Loader.php的第187行左右加入如下代码即可

                $this->_ci_assign_to_models();
这个是调用CI自身的机制将新创建的对像引用到当前所有存在的对像中。
CI这块的代码比较饶。

不知道这是不是CI的BUG,还是说CI本身的格式要求就是不在model中调用model,

个人感觉如果不能在model中调用model那代码量会上升非常多,不同model间的接口和数据传递不能做到,model也真就成了只是处理数据库的一个东西了。程序的继承多态复用也就无从说起。
 楼主| 发表于 2010-11-16 00:27:34 | 显示全部楼层
版本是最新的1.7.2
发表于 2010-11-16 01:30:46 | 显示全部楼层
这不是BUG,是CI的一个约束,或者说是因为MVC结构造成的。

如果出现在Model中调用Model的情况,一般是因为:
1. 数据建模没有做好,建议重新建模。
2. 还没有深刻理解MVC的含义。Model需要耦合性低,具有高度的自治性。传统的MVC来说,Model与Model之前是不需要,也不应该有交互的。

当然了,解决办法不是没有,看这里:
http://codeigniter.com/forums/viewthread/83035/P0/

PS: 修改了一下你的标题,有错别字呢。

MVC介绍参考:http://zh.wikipedia.org/zh/MVC

评分

参与人数 1威望 +2 收起 理由
Hex + 2 我很赞同

查看全部评分

发表于 2010-11-16 11:08:15 | 显示全部楼层
当然可以。就是这样用的
一个控制器引入多个模型
模型间互相调用就没有问题。随便你新建哪个模型的对象只要在控制器里面引入过就可以新建。他们是一体的。
 楼主| 发表于 2010-11-16 22:39:42 | 显示全部楼层
本帖最后由 yangzhu 于 2010-11-16 22:51 编辑

公司的框架直接是充许在model中调用model的。所以我之前一直不知道CI有这个约束。只是很奇怪,如果模型间不能相互调用那么控制器中势必要调用多个模型,并且在不同的模型方法中传递数据。控制器中一定会有大量的调用。当然一个流程下来还是蛮清晰的。但是如果充许在模型中调用模型可以把一次需要的数据处理好再返回给控制器。控制器中不需要了解模型内部的数据调用。只有在需要了解模型内部机制的时候去处理就OK了。相当于是对外部的一次封装。 当然模型间的耦合确实难以避免。

举个例子

取一个文章列表 同时取出对应的分类名称

比如我的做法是建两个模型,一个分类模型,一个文章模型
class article exten extends Model{
....
       public function getArticleList()
      {
              $sql = 'select * from article'
...
               $this->load->model('articleclass');
               $articleclassList = $this->articleclass->getArticleclassList();
               while($row = mysql_fetch_assoc($query))
               {
                        $row['articleclassName'] =  $articleclassList[$row['articleclassId']]['name'];
                        $list[] = $row;
               }
                return $list;
      }
}

class articleclass exten extends Model{
....
       public function getArticleclassList()
      {
              $sql = 'select * from articleclass'
...
                while($row = mysql_fetch_assoc($query))
              {
                   $list[$row['id']] = $row;
               }
                return $list;
      }
}

我在模型中直接处理好了对关联数据的整合,外部控制器中可以很清晰的调用getArticleList就可以获取数据。并且对getArticleList这个方法可以加上缓存,很容易处理。

如果是在外部控制器对数据进行整理那么就必定需要循环articltlist对每条记录进行整理。一则是外部控制器很难看。二是没法对合并整理后的数据进行缓存。或者是需要再调用一个方法进行缓存的处理。首先就循环上来说多了一次循环。处理流程更繁琐。
 楼主| 发表于 2010-11-16 22:54:20 | 显示全部楼层
当然可以。就是这样用的
一个控制器引入多个模型
模型间互相调用就没有问题。随便你新建哪个模型的对象只要 ...
sonic 发表于 2010-11-16 11:08



    这样的方式可以实现,但是在控制器中就加载了所有可能用到的类并实例化为对像(这个对像可能在后面的条件判断后并不需要实例化),系统的性能直线下降了。如果充行在模型中调用模型那么就不存在这个问题,可以在确实需要的时候才去加载并实例化。
 楼主| 发表于 2010-11-17 00:05:31 | 显示全部楼层
又去了解了一下松耦合的东西,确实一定程度上牺牲了效率。公司的项目对性能要求都比较高。可能也是采用这样模式的原因吧。 对这种结构上的东西还有太多的需要学。   功能都能实现,但怎么样实现才是最好的,这个可能要学一辈子。
发表于 2010-11-17 09:52:45 | 显示全部楼层
这个你需要和公司的测试程序员沟通的。
PHP不是C++需要注意那么多销毁操作.
可能你是一个C++程序员。

本版积分规则