ThinkPHP3.2.3的钩子方法使用

ThinkPHP3.2.3的钩子方法使用

在Library/Think/Model.class.php 这个基础model类中在添加add,修改save,和删除delete 时各自回调用两个回调函数. 使用这两个回调函数会给开发带来方便.

1 . add()方法回调函数

// 插入数据前的回调方法
protected function _before_insert(&$data,$options) {}
// 插入成功后的回调方法
protected function _after_insert($data,$options) {}

2 . save()方法回调函数

// 更新数据前的回调方法
protected function _before_update(&$data,$options) {}
// 更新成功后的回调方法
protected function _after_update($data,$options) {}

3 .delete()方法回调方法

// 删除数据前的回调方法
protected function _before_delete($options) {}    
// 删除成功后的回调方法
protected function _after_delete($data,$options) {}

4.使用场景是什么?

1 ._before_insert()

//添加前
protected function _before_insert(&$data, $option)
{
    // 添加管理员之前先加密
    $data['password'] = md5($data['password'] . C('MD5_KEY'));
}

上面就是我们在插入数据库之前,对password字段进行md5加密.格式必须是 $data[‘字段名’] . 这个字段名就是你要插入到数据表中的字段.

2 ._after_insert()

// 添加后
protected function _after_insert($data, $option)
{
    // 处理管理员所在角色
    $roleId = I('post.role_id');
    if($roleId)
    {
        $raModel = M('RoleAdmin');
        foreach ($roleId as $k => $v)
        {
            $raModel->add(array(
                'admin_id' => $data['id'], // 添加之后的管理员的ID
                'role_id' => $v,
            ));
        }
    }
}

上面是定义在管理员模型中的方法 . 它的html页面是添加管理员的同时给管理员分配角色 . 所以收集到的表单中有 有admin表的信息以及role_id . 上面代码实现的是 向 admin_role 这个中间表中插入数据, 此时role_id 可以通过表单提交收集到, 但是缺少admin_id .这个admin_id 就是 $data[‘admin表的主键’]

3 ._before_update()

// 修改前
protected function _before_update(&$data, $option)
{
    // 处理管理员所在角色
    // 先删除中间表中原来的数据
    $raModel = M('RoleAdmin');
    $raModel->where(array(
        'admin_id' => $option['where']['id'],
    ))->delete();
    // 重新把新选择的添加一遍
    $roleId = I('post.role_id');
    if($roleId)
    {
        foreach ($roleId as $k => $v)
        {
            $raModel->add(array(
                'admin_id' => $option['where']['id'], // 添加之后的管理员的ID
                'role_id' => $v,
            ));
        }
    }
    // 判断如果密码为空就不修改密码【从表单数组中把这一项删除】
    if(empty($data['password']))
        unset($data['password']);
    else 
        $data['password'] = md5($data['password'] . C('MD5_KEY'));
}

这里有两点.第一:如果你需要在修改前对数据进行处理.格式 仍然是 $data[‘字段’]

$data['password'] = md5($data['password'] . C('MD5_KEY'));

第二:如果你要先中间表中插入数据,缺少的admin_id 此时是$options[‘where’][‘主键’]

4 ._after_update()

$options[‘where’][‘主键’]

5 . _before_delete()

// 删除前
protected function _before_delete($option)
{
    if($option['where']['id'] == 1)
    {
        $this->error = '超级管理员不能被删除!';
        return FALSE;
    }
    // 把中间表中对应的数据也删除
    $raModel = M('RoleAdmin');
    $raModel->where(array(
        'admin_id' => array('eq', $option['where']['id']),
    ))->delete();
}

$option[‘where’][‘主键’]

总结:

1 . 在insert 中如果想要获得主键,就是 data[], data[‘id’]

2 .在update,delete 想要获得主键就是$options[‘where’][‘主键’]

如果在这些回调方法中出现错误,怎们处理

protected function _before_delete($option)
{
    if($option['where']['id'] == 1)
    {
        $this->error = '超级管理员不能被删除!';
        return FALSE;
    }

将错误赋值给 模型中的error变量, 同时返回false. 这样这个错误,就可以用模型的getError()方法获取了.Model.class.php中的getError()方法

/**
 * 返回模型的错误信息
 * @access public
 * @return string
 */
public function getError(){
    return $this->error;
}

5.查看Model.class.php中的源码.

add()方法

public function add($data='',$options=array(),$replace=false) {
    if(empty($data)) {
        // 没有传递数据,获取当前数据对象的值
        if(!empty($this->data)) {
            $data           =   $this->data;
            // 重置数据
            $this->data     = array();
        }else{
            $this->error    = L('_DATA_TYPE_INVALID_');
            return false;
        }
    }
    // 分析表达式
    $options    =   $this->_parseOptions($options);
    // 数据处理
    $data       =   $this->_facade($data);
  A处:  if(false === $this->_before_insert($data,$options)) {
        return false;
    }
    // 写入数据到数据库
    $result = $this->db->insert($data,$options,$replace);
    if(false !== $result ) {
        $insertId   =   $this->getLastInsID();
        if($insertId) {
            // 自增主键返回插入ID
            $data[$this->getPk()]  = $insertId;
       B处:     $this->_after_insert($data,$options);
            return $insertId;
        }
        $this->_after_insert($data,$options);
    }
    return $result;
}

上面A处时调用_before_insert. 这里是判断是否是false, 如果是false ,add()方法也返回false . 所以这就就是我们在_before_insert中出现错误的时候要返回false的原因

B处前一行代码,可以看出在插入数据后,将最新的主键保存到了$data[‘主键’]中.

save()方法:

public function save($data='',$options=array()) {
    if(empty($data)) {
        // 没有传递数据,获取当前数据对象的值
        if(!empty($this->data)) {
            $data           =   $this->data;
            // 重置数据
            $this->data     =   array();
        }else{
            $this->error    =   L('_DATA_TYPE_INVALID_');
            return false;
        }
    }
    // 数据处理
    $data       =   $this->_facade($data);
    // 分析表达式
    $options    =   $this->_parseOptions($options);
    $pk         =   $this->getPk();
    if(!isset($options['where']) ) {
        // 如果存在主键数据 则自动作为更新条件
        if(isset($data[$pk])) {
         A处:   $where[$pk]         =   $data[$pk];
            $options['where']   =   $where;
            unset($data[$pk]);
        }else{
            // 如果没有任何更新条件则不执行
            $this->error        =   L('_OPERATION_WRONG_');
            return false;
        }
    }
 B处:   if(is_array($options['where']) && isset($options['where'][$pk])){
        $pkValue    =   $options['where'][$pk];
    }        
    if(false === $this->_before_update($data,$options)) {
        return false;
    }        
    $result     =   $this->db->update($data,$options);
    if(false !== $result) {
        if(isset($pkValue)) $data[$pk]   =  $pkValue;
        $this->_after_update($data,$options);
    }
    return $result;
}

如果你使用了连贯操作,直接到B处.

如果没有使用连贯操作,从A处,将主键保存到 option[where][], data[‘主键’]

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值