paperen 发表于 2011-10-13 09:48:26

关于模型的一些疑惑

本帖最后由 paperen 于 2011-10-13 19:09 编辑

大虾们,有个问题迷惑我很久了,是关于模型部分的,一开始就贴上模型部分的代码。

/**
* 用户模型
*/
class User_model extends CI_Model
{
    /**
   * table映射
   * @var array
   */
    private $_table = array(
      'user' => 'user',
      'group' => 'group',
    );

    /**
   * 字段映射
   * @var array
   */
    private $_fields = array(
      'user' => array(
            'id' => 'id',
            'username' => 'username',
            'password' => 'password',
            'groupid' => 'groupid',
      ),
      'group' => array(
            'id' => 'id',
            'name' => 'name',
      ),
    );

    /**
   * 根据用户ID查询用户信息
   * @param int $userid 用户ID
   * @return array 用户数据
   */
    public function get( $userid )
    {
      return $this->db->from( $this->_table['user'] )
                        ->where( $this->_fields['user']['id'], $userid )
                        ->get()
                        ->row_array();
    }

    /**
   * 用户验证
   * @param string $username 用户帐号
   * @param string $password 用户密码
   * @return array 用户数据
   */
    public function verify( $username, $password )
    {
      return $this->db->from( $this->_table['user'] )
                        ->where( $this->_fields['user']['username'], $username )
                        ->where( $this->_fields['user']['password'], $password )
                        ->get()
                        ->row_array();
    }

    /**
   * 在控制器中就决定查询哪些字段决定where
   * @param arrray $where 限制条件
   * @param string $select 查询字段
   * @return array 查询结果
   */
    public function get2( $where, $select = '*' )
    {
      return $this->db->select( $select )
                        ->from( 'user' )
                        ->where( $where )
                        ->get()
                        ->row_array();
    }
}

那些表映射、字段映射都是在开发过程中按照自己的想法加上的,也不是一定这么做才规范,而其实get属于get2的一种情况,相对而言get2的灵活性更大,这正是我的疑问所在。


因为我规定了不要在控制器对模型有任何决定的动作,也就是get2参数的$where与$select,我当初的想法是,既然控制器与模型分开那么就不要在控制器中进行查询控制,而是相应地在模型中根据控制器需求建立不同的方法,即使查询的数据大致一样(只是这个方法不需要查询用户的密码字段,而那个方法则需要),那么就会在模型中出来两个方法,比如:get($userid)是根据用户ID获取用户全部数据的,而verify($username, $password)是判断用户登陆是否合法的。但get2这个方法就能包括了get与verify这两个方法的功能。

控制器部分代码

//引入用户模型
      $this->load->model( 'user_model' );

      //用户ID
      $userid = 1;
      //用户名
      $username = 'test';
      //用户密码
      $password = 'test';

      //get
      //获取确定ID的用户数据
      
      $user_data = $this->user_model->get( $userid );

      //verify
      //验证用户是否合法
      $valid_user = $this->user_model->verify( $username, $password );

      //get2
      //在控制器中可以决定查询的限制条件
      //不需要查询到password字段
      $select = 'id,username';
      //条件
      $where = array( 'id' => $userid );
      $user_data = $this->user_model->get2( $where, $select );

      //get2
      //比如登陆验证时还可以重用get2这个方法
      $where = array( 'username' => $username, 'password' => $password );
      $valid_user = $this->user_model->get2( $where );


get2这个方法就已经包括了两种需求,查询用户数据与验证用户合法性。但是当表结构发生改动时,我们要修改的就不是模型了而是控制器了,而这点我认为与MVC的思路不符合。

不知道各位大虾有没有相关的经验,告诉我到底我应该坚持原来自己的想法还是改变,或者还有更好的思路。求教!

Hex 发表于 2011-10-13 16:39:38

我觉得应该去掉 get2 这种方法。
否则和直接写 SQL 语句没有本质上的区别。

paperen 发表于 2011-10-13 19:00:12

Hex 发表于 2011-10-13 16:39 static/image/common/back.gif
我觉得应该去掉 get2 这种方法。
否则和直接写 SQL 语句没有本质上的区别。

那您的意见就是不推荐在控制器中对模型查询有任何控制对不?

Hex 发表于 2011-10-13 20:08:06

paperen 发表于 2011-10-13 19:00 static/image/common/back.gif
那您的意见就是不推荐在控制器中对模型查询有任何控制对不?

是的,原则上控制器不应该知道模型是如何实现的。
SQL 本身就是内部实现,当然不适合出现在控制器中。

paperen 发表于 2011-10-13 20:55:17

Hex 发表于 2011-10-13 20:08 static/image/common/back.gif
是的,原则上控制器不应该知道模型是如何实现的。
SQL 本身就是内部实现,当然不适合出现在控制器中。 ...

i get it.thanks

嘟嘟返利 发表于 2011-10-13 20:55:18

应该把SQL放到Model中

paperen 发表于 2011-10-13 20:56:35

嘟嘟返利 发表于 2011-10-13 20:55 static/image/common/back.gif
应该把SQL放到Model中

嗯嗯

大道达人 发表于 2011-10-14 11:12:34

sql要和model走

shuiping56 发表于 2011-10-17 09:56:59

大虾们,MVC是否可以这样做呢?
M层:操作了数据库,并且把取出了的数据整理好,然后return数据。
C层:从M层取得数据,根据取得的数据的情况,控制跳转不同的视图。取得用户输入的数据,并

进行合法验证,数据过滤,然后再传给M层。
V层:取得C层的数据,绑定数据。
如果是这样理解的话,那么:
建立一个C层文件,写一个function,对应着一个视图。
建立一个M层文件,写一个function(名字和C层的function同名),从数据库取数据,然后整理

数据,然后给C层的一个function。
V层:获取C层数据,绑定数据。

大虾们,是不是可以这样做呢?这样做对不对呢?

acabin 发表于 2011-10-27 15:23:57

事实上,应该根据不同的业务需求,把get2拆分为例如getUsernameById,getAddressById之类的
页: [1]
查看完整版本: 关于模型的一些疑惑