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

[模型] 关于模型的一些疑惑

[复制链接]
发表于 2011-10-13 09:48:26 | 显示全部楼层 |阅读模式
本帖最后由 paperen 于 2011-10-13 19:09 编辑

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

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这两个方法的功能。

控制器部分代码
PHP复制代码
 
//引入用户模型
        $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的思路不符合。

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

发表于 2011-10-13 16:39:38 | 显示全部楼层
我觉得应该去掉 get2 这种方法。
否则和直接写 SQL 语句没有本质上的区别。
 楼主| 发表于 2011-10-13 19:00:12 | 显示全部楼层
Hex 发表于 2011-10-13 16:39
我觉得应该去掉 get2 这种方法。
否则和直接写 SQL 语句没有本质上的区别。

那您的意见就是不推荐在控制器中对模型查询有任何控制对不?
发表于 2011-10-13 20:08:06 | 显示全部楼层
paperen 发表于 2011-10-13 19:00
那您的意见就是不推荐在控制器中对模型查询有任何控制对不?

是的,原则上控制器不应该知道模型是如何实现的。
SQL 本身就是内部实现,当然不适合出现在控制器中。
 楼主| 发表于 2011-10-13 20:55:17 | 显示全部楼层
Hex 发表于 2011-10-13 20:08
是的,原则上控制器不应该知道模型是如何实现的。
SQL 本身就是内部实现,当然不适合出现在控制器中。 ...

i get it.thanks
发表于 2011-10-13 20:55:18 | 显示全部楼层
应该把SQL放到Model中
 楼主| 发表于 2011-10-13 20:56:35 | 显示全部楼层
嘟嘟返利 发表于 2011-10-13 20:55
应该把SQL放到Model中

嗯嗯
发表于 2011-10-14 11:12:34 | 显示全部楼层
sql要和model走
发表于 2011-10-17 09:56:59 | 显示全部楼层
大虾们,MVC是否可以这样做呢?
M层:操作了数据库,并且把取出了的数据整理好,然后return数据。
C层:从M层取得数据,根据取得的数据的情况,控制跳转不同的视图。取得用户输入的数据,并

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

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

大虾们,是不是可以这样做呢?这样做对不对呢?
发表于 2011-10-27 15:23:57 | 显示全部楼层
事实上,应该根据不同的业务需求,把get2拆分为例如getUsernameById,getAddressById之类的

本版积分规则